Пример:
Таблица БД tab состоящая из 1 000 000 строк (все поля - INT).
id...........|.pole_m.|.pole_1.|.pole_2.|.pole_3.|.pole_4|
1............|....12.....|....3......|.....4....|.....4.....|.....7.....|
……
……
1000000..|.....3.....|.....6.....|.....2....|.....1.....|.... 6 ....|
При первом (! Это важно) запуске скрипта в эту таблицу производятся такие запросы
1. SELECT COUNT (*) FROM `tab` WHERE `pole_m`=’1’
2. SELECT COUNT (*) FROM `tab` WHERE `pole_m`=’6’
3. SELECT COUNT (*) FROM `tab` WHERE `pole_m`=’8’
4. SELECT COUNT (*) FROM `tab` WHERE ` pole_1`=’12’
5. SELECT COUNT (*) FROM `tab` WHERE ` pole_1`=’4’
6. SELECT COUNT (*) FROM `tab` WHERE ` pole_2`=’12’
7. SELECT COUNT (*) FROM `tab` WHERE ` pole_2`=’8’
8. SELECT COUNT (*) FROM `tab` WHERE ` pole_2`=’1’
….
20. SELECT COUNT (*) FROM `tab` WHERE ` pole_4`=’7’ т.е запрос происходит строго по одному полю
При втором…третьем и далее запусках скрипта запросы могут остаться такими же (!), а могут измениться на:
SELECT COUNT (*) FROM `tab` WHERE `pole_m`=’1’ AND `pole_3`=’12’или
SELECT COUNT (*) FROM `tab` WHERE `pole_4`=’1’ AND `pole_3`=’12’или
SELECT COUNT (*) FROM `tab` WHERE `pole_m`=’1’ AND `pole_1`=’12’ AND `pole_2`=’4’ AND `pole_3`=’8’ AND `pole_4`=’2’
Пробуя разные варианты, я пришел к выводу (да и по логике), что при первом запуске (когда в запросе сортировка идет строго по одному полю) лучше чтоб индексация была по конкретным столбцам т.е. отдельно по `pole_m` …`pole_4` т.к.
При повторных запусках могут быть запросы полного вида, например:
SELECT COUNT (*) FROM `tab` WHERE `pole_m`=’1’ AND `pole_1`=’12’ AND `pole_2`=’4’ AND `pole_3`=’8’ AND `pole_4`=’2’
Тут естественно намного быстрее будет работать составной индекс (`pole_m` …`pole_4`), но если запрос будет, скажем:
SELECT COUNT (*) FROM `tab` WHERE `pole_4`=’1’ AND `pole_3`=’12’то составной индекс (`pole_m` …`pole_4`) работать уже не будет и под него лучше было бы иметь составной индекс (`pole_3`,`pole_4`)
Хочу напомнить запросы могут быть и простые с сортировкой по одному полю.
Поэтому я пришел к выводу, что в этой ситуации лучше отказать от составных индексов, а использовать одиночные.
Хотелось бы услышать Ваше мнение по этому поводу.
Спустя 28 минут, 19 секунд (18.11.2011 - 08:35) Michael написал(а):
составной индекс - все таки больше для поддержания целостности по первичному ключу. А для поиска - да, обычные индексы.
Спустя 5 минут, 36 секунд (18.11.2011 - 08:41) GET написал(а):
Michael
интересно, что я даже пытался обмануть MySQL и запрос вида SELECT COUNT (*) FROM `tab` WHERE `pole_3`=’12’
переделывал вот так:
SELECT COUNT (*) FROM `tab` WHERE `pole_m`>'0' AND `pole_1`>'0' AND `pole_2`>'0' AND `pole_3`='12' AND `pole_4`>'0'
чтоб заставить работать составной индекс, но затея провалилась
интересно, что я даже пытался обмануть MySQL и запрос вида SELECT COUNT (*) FROM `tab` WHERE `pole_3`=’12’
переделывал вот так:
SELECT COUNT (*) FROM `tab` WHERE `pole_m`>'0' AND `pole_1`>'0' AND `pole_2`>'0' AND `pole_3`='12' AND `pole_4`>'0'
чтоб заставить работать составной индекс, но затея провалилась
Спустя 49 минут, 52 секунды (18.11.2011 - 09:31) Michael написал(а):
Ты просто почитай теорию - что такое индекс вообще. Как он хранится. Сразу все поймешь.
В кратце:
Есть у тебя таблица
Составной индекс(*)
создаст отсортированную копию твоей таблицы из этих полей со ссылками на реальные записи.
Это означает что имея индекс (*) ты имеешь индекс
и
т.к. они слева
А индекса по pole_3 у тебя просто нет(pole_3 у тебя отсортирован по первым двум, а не по себе) и все и кого тут обманывать?
В кратце:
Есть у тебя таблица
pole_1 pole_2 pole_3 pole_4
Составной индекс(*)
pole_1 pole_2 pole_3
создаст отсортированную копию твоей таблицы из этих полей со ссылками на реальные записи.
Это означает что имея индекс (*) ты имеешь индекс
pole_1 pole_2
и
pole_1
т.к. они слева
А индекса по pole_3 у тебя просто нет(pole_3 у тебя отсортирован по первым двум, а не по себе) и все и кого тут обманывать?
Спустя 55 минут, 4 секунды (18.11.2011 - 10:26) caballero написал(а):
составной индек имеет смысл если поиск или сортировка или группировка выполняется одновременно по этим полям
Спустя 2 минуты, 4 секунды (18.11.2011 - 10:28) Michael написал(а):
Цитата (caballero @ 18.11.2011 - 09:26) |
индек |
индюк?
Спустя 1 час, 49 минут, 46 секунд (18.11.2011 - 12:18) GET написал(а):
Я понимаю, как устроен индекс
Цитата |
А индекса по pole_3 у тебя просто нет(pole_3 у тебя отсортирован по первым двум, а не по себе) и все и кого тут обманывать? |
le
Я имел ввиду если первых двух нет, то поставить для них `pole_1`>'0' AND `pole_2`>'0' т.е. сделать так как будто они есть, в этом смысле обмануть
Я имел ввиду если первых двух нет, то поставить для них `pole_1`>'0' AND `pole_2`>'0' т.е. сделать так как будто они есть, в этом смысле обмануть
Спустя 2 минуты, 50 секунд (18.11.2011 - 12:20) Michael написал(а):
Цитата (A.B.C. @ 18.11.2011 - 11:18) |
Я понимаю, как устроен индекс |
ты не понимаешь как устроен индекс, т.к. несешь какую то ахинею:
Цитата (A.B.C.) |
Я имел ввиду если первых двух нет, то поставить для них `pole_1`>'0' AND `pole_2`>'0' т.е. сделать так как будто они есть, в этом смысле обмануть |
Спустя 25 минут, 53 секунды (18.11.2011 - 12:46) GET написал(а):
Michael
Почему?
`pole_1`>'0' это значит все значения, `pole_2`>'0' тоже...будет перебор всех строк просто, понятно, что смысла в этом нет, но все же последнее поле `pole_3` будет отсортировано, как надо
Почему?
`pole_1`>'0' это значит все значения, `pole_2`>'0' тоже...будет перебор всех строк просто, понятно, что смысла в этом нет, но все же последнее поле `pole_3` будет отсортировано, как надо
Спустя 1 час, 33 минуты, 28 секунд (18.11.2011 - 14:20) Michael написал(а):
может быть я и понял о чем ты речь ведешь. Но неуверен. . Посмотри использование use index. Может оно...
Спустя 6 минут, 22 секунды (18.11.2011 - 14:26) GET написал(а):
Michael
Спасибо, почитаю, хотя видел аналог этой статьи на русском, на mysql.ru
Спасибо, почитаю, хотя видел аналог этой статьи на русском, на mysql.ru
_____________
Не тот велик, кто не падал, а тот кто падал и поднимался.