Този начин също не е необичаен:
ИЗБЕРЕТЕ s1.*ОТ студенти s1LEFT ПРИСЪЕДИНЕТЕ студенти s2 ON s1.rank
LEFT JOIN работи въз основа на това, че когато s1.rank е на максималната си стойност, няма s2.rank с по-голяма стойност и стойностите на s2 редовете ще бъдат NULL.
Но бих казал, че вашият начин да го направите е най-разпространеният, най-лесният за разбиране начин да го направите, да.
РЕДАКТИРАНЕ:На въпроса защо понякога е по-бавно:
Изпълнението на тази заявка зависи от това "колко внимателно е написано". Вземете вашите данни за пример:
пуснете таблицата, ако съществува студенти;СЪЗДАВАЙТЕ ТАБЛИЦА ученици (`uid` bigint, `last_name` varchar(5), `first_name` varchar(8), `dob` varchar(10), `email` varchar( 16), `rank` int, `grade` int);INSERT INTO students (`uid`, `last_name`, `first_name`, `dob`, `email`, `rank`, `grade`)СТОЙНОСТИ (13428700000001, „Смит“, „Джон“, „1990-12-03“, „ample. com
', 99, 4), (13428721960000, 'Li', 'Kai Li', '1979-02-15', '[email protected]
', 12, 2), (13428722180001, 'Zhang', 'Xi Xiong', '1993-11-09', '[email protected]
', 5, 5), (13428739950000, 'Zhou', 'Ji Hai', '1991-06-06', '[email protected]
', 234, 1), (13428739950001, 'Pan', 'Yao', '1992-05-12', '[email protected]
', 43, 2), (13428740010001, 'Jin', 'Denny', '1994-06-02', '[email protected]
', 198, 3), (13428740010002, 'Li', 'Fonzie', '1991-02-02', '[email protected]
', 75, 3), (13428743370000, 'Ma', 'Haggar', '1991-08-16', '[email protected]
', 47, 4), (13428743590001, 'Ren', 'Jenny', '1990-03-29', '[email protected]
', 5, 2), (13428774040000, 'Чен', 'Дракон', '1999-04-12', '[email protected]
', 23, 5), (13428774260001, 'Уанг', 'Доктор', '1996-09-30', '[email protected]
', 1, 5), (13430100000000, 'Chanz', 'Heyvery', '1994-04-04', '[email protected]
', 107, 2);
Обяснението на вашата заявка изглежда така:
<предварителен код>| ID | SELECT_TYPE | ТАБЛИЦА | ТИП | POSSIBLE_KEYS | КЛЮЧ | KEY_LEN | REF | РЕДОВЕ | ДОПЪЛНИТЕЛНО |------------------------------------------------ -------------------------------------------------- -----| 1 | ОСНОВНО | студенти | ВСИЧКИ | (нула) | (нула) | (нула) | (нула) | 12 | Използване на където || 2 | ПОДЗАПЕРКА | студенти | ВСИЧКИ | (нула) | (нула) | (нула) | (нула) | 12 | |Този от моята заявка е така:
<предварителен код>| ID | SELECT_TYPE | ТАБЛИЦА | ТИП | POSSIBLE_KEYS | КЛЮЧ | KEY_LEN | REF | РЕДОВЕ | ДОПЪЛНИТЕЛНО |------------------------------------------------ -------------------------------------------------- --| 1 | ПРОСТО | s1 | ВСИЧКИ | (нула) | (нула) | (нула) | (нула) | 12 | || 1 | ПРОСТО | s2 | ВСИЧКИ | (нула) | (нула) | (нула) | (нула) | 12 | Използване на where |
Почти същото. Нито една заявка не използва индекс, всички редове се сканират. Сега добавяме индекс към колона rank
.
пуснете таблицата, ако съществува студенти;СЪЗДАВАЙТЕ ТАБЛИЦА ученици (`uid` bigint, `last_name` varchar(5), `first_name` varchar(8), `dob` varchar(10), `email` varchar( 16), `rank` int, `grade` int , ключ rankkey(rank) );
Обяснението от вашата заявка:
<предварителен код>| ID | SELECT_TYPE | ТАБЛИЦА | ТИП | POSSIBLE_KEYS | КЛЮЧ | KEY_LEN | REF | РЕДОВЕ | ДОПЪЛНИТЕЛНО |------------------------------------------------ -------------------------------------------------- ---------------------------| 1 | ОСНОВНО | студенти | ref | rankkey | rankkey | 5 | const | 1 | Използване на където || 2 | ПОДЗАПЕРКА | (нула) | (нула) | (нула) | (нула) | (нула) | (нула) | (нула) | Изберете оптимизирани таблици |срещу моята:
<предварителен код>| ID | SELECT_TYPE | ТАБЛИЦА | ТИП | POSSIBLE_KEYS | КЛЮЧ | KEY_LEN | REF | РЕДОВЕ | ДОПЪЛНИТЕЛНО |------------------------------------------------ -------------------------------------------------- --| 1 | ПРОСТО | s1 | ВСИЧКИ | (нула) | (нула) | (нула) | (нула) | 12 | || 1 | ПРОСТО | s2 | ВСИЧКИ | rankkey | (нула) | (нула) | (нула) | 12 | Използване на where |Вашата заявка използва индекса, моята не.
Сега добавяме първичен ключ към таблицата.
пуснете таблицата, ако съществува студенти;СЪЗДАВАЙТЕ ТАБЛИЦА ученици (`uid` bigint, `last_name` varchar(5), `first_name` varchar(8), `dob` varchar(10), `email` varchar( 16), `rank` int, `grade` int , ключ rankkey(rank) , първичен ключ(uid) );
Обяснете от вашата заявка:
<предварителен код>| ID | SELECT_TYPE | ТАБЛИЦА | ТИП | POSSIBLE_KEYS | КЛЮЧ | KEY_LEN | REF | РЕДОВЕ | ДОПЪЛНИТЕЛНО |------------------------------------------------ -------------------------------------------------- ---------------------------| 1 | ОСНОВНО | студенти | ref | rankkey | rankkey | 5 | const | 1 | Използване на където || 2 | ПОДЗАПЕРКА | (нула) | (нула) | (нула) | (нула) | (нула) | (нула) | (нула) | Изберете оптимизирани таблици |и от моята:
<предварителен код>| ID | SELECT_TYPE | ТАБЛИЦА | ТИП | POSSIBLE_KEYS | КЛЮЧ | KEY_LEN | REF | РЕДОВЕ | ДОПЪЛНИТЕЛНО |------------------------------------------------ -------------------------------------------------- -------------------------------------| 1 | ПРОСТО | s1 | ВСИЧКИ | (нула) | (нула) | (нула) | (нула) | 12 | || 1 | ПРОСТО | s2 | индекс | rankkey | rankkey | 5 | (нула) | 12 | Използване къде; Използване на индекс; Не съществува |По този начин най-вероятно са еднакво бързи. И така обикновено се изграждат заявката и таблицата. Всяка таблица трябва да има първичен ключ и ако много често изпълнявате филтриране на заявка в колоната за ранг, разбира се, трябва да имате индекс върху нея. Така че почти няма разлика. Сега всичко зависи от това колко редове имате във вашата таблица, дали е уникален индекс и/или клъстериран. Но това би довело сега малко твърде далеч. Но имайте предвид, че в този пример има разлика в това колко редове се изследват. При малки данни няма разлика, при големи обеми от данни със сигурност има. Но(!) това поведение може да се промени и за двете заявки, в зависимост от индекса.
Ами ако този, който пише заявката, направи грешка? Ами ако го напише така:
ИЗБЕРЕТЕ s1.*ОТ студенти s1LEFT ПРИСЪЕДИНЕТЕ студенти s2 ON s1.rank
Заявката все още работи и е валидна, но
<предварителен код>| ID | SELECT_TYPE | ТАБЛИЦА | ТИП | POSSIBLE_KEYS | КЛЮЧ | KEY_LEN | REF | РЕДОВЕ | ДОПЪЛНИТЕЛНО |------------------------------------------------ -------------------------------------------------- --| 1 | ПРОСТО | s1 | ВСИЧКИ | (нула) | (нула) | (нула) | (нула) | 12 | || 1 | ПРОСТО | s2 | ВСИЧКИ | rankkey | (нула) | (нула) | (нула) | 12 | Използване на where |отново индексът не се използва.
Ами ако премахнем отново първичния ключ и напишем заявката така:
ИЗБЕРЕТЕ s1.*ОТ студенти s1LEFT ПРИСЪЕДИНЕТЕ студенти s2 ON s1.rank
Индексът се използва отново.
Заключение: И двете заявки трябва да се изпълняват еднакво бързо, ако са направени правилно. Вашата е бърза, стига индексът да е в колона за ранг. Същото важи и за моя, ако е написано с индекси.
Надявам се това да помогне.