#php #mysql #indexing
#php #mysql #индексирование
Вопрос:
Я выбираю данные из таблицы базы данных mysql. Когда я ищу определенную дату, мой индекс работает нормально. Когда я ищу данные между двумя датами, индекс не работает, и запрос занимает много времени. Есть ли у кого-нибудь идея, как я могу улучшить запрос или индекс?
Запрос A:
EXPLAIN SELECT * FROM sal_import
WHERE dateStats>="2011-07-28" AND dateStats<="2011-07-30" GROUP BY f_shop
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE i range dateStats dateStats 3 (NULL) 7896 Using where; Using temporary; Using filesort
Запрос B:
EXPLAIN SELECT * FROM sal_import i
WHERE dateStats="2011-07-30" GROUP BY f_shop
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE i ref dateStats dateStats 3 const 2182 Using where
Это индекс таблицы:
ALTER TABLE sal_import ADD INDEX(dateStats,f_shop);
Большое вам спасибо.
Комментарии:
1. когда я удаляю предложение group by, индекс работает нормально. является ли это хорошим решением для группировки значений в php?
Ответ №1:
Попробуйте это:
SELECT * FROM sal_import WHERE dateStats BETWEEN '2011-07-28' AND '2011-07-30'
Также смотрите http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html
Комментарии:
1. привет, сначала я думал, что функция between была моей проблемой, поэтому я изменил ее на текущий запрос. Это означает, что функция explain сообщает мне об одной и той же проблеме между ними.
2. -1 Причина в том, что это неправильный тип индекса.
BETWEEN
это просто синтаксический сахар.3. Что значит «неправильный тип индекса»? Когда индекс не кратен, у меня та же проблема.
4. Смотрите мой ответ ниже. Столбец даты является вторичным индексом, что означает, что он не упорядочен последовательно; таким образом, его можно использовать для поиска, но не для поиска по диапазону.
5. * ну, это возможно, но для этого требуется, чтобы данные снова собирались вместе, а не считывались последовательно с диска. При небольшом количестве записей полное сканирование таблицы может быть быстрее, чем при использовании вторичного индекса.
Ответ №2:
Причина в том, что индекс даты не является кластеризованным, и поэтому данные не упорядочиваются последовательно по этому ключу на диске. В вашей таблице небольшое количество записей, поэтому оптимизатор запросов решил, что быстрее выполнить полное сканирование таблицы, а не использовать вторичный индекс и собирать записи вместе.
Таблица может иметь только один кластеризованный индекс, и обычно это первичный ключ. Столбец даты, как правило, является допустимым и разумным столбцом для размещения кластеризованного индекса, но это может быть не лучшим его использованием; это действительно зависит от того, как используется эта таблица.
http://msdn.microsoft.com/en-us/library/aa933131 (v=sql.80).aspx
К сожалению, в MySQL кластеризованный индекс должен находиться в уникальном столбце, и вы не можете определить кластеризованный индекс для столбца (по-видимому); база данных выбирает этот индекс для вас по умолчанию. Учитывая это, вам может не повезти в этом.
http://dev.mysql.com/doc/refman/5.0/en/innodb-index-types.html