Улучшение таблиц MySQL с помощью индексов - PullRequest
12 голосов
/ 19 апреля 2011

Я очень плохо знаком с индексами в MySQL.Я знаю, наверное, мне следовало бы приступить к этому раньше, но большинство проектов было достаточно маленьким, чтобы я смог с ним справиться;)

Итак, сейчас я тестирую его.Я сделал свой тест, запустив EXPLAIN для запроса:

Запрос:

EXPLAIN SELECT a . *
FROM `tff__keywords2data` AS a
LEFT JOIN `tff__keywords` AS b ON a.keyword_id = b.id
WHERE (
b.keyword = 'dog' || b.keyword = 'black' || b.keyword = 'and' || b.keyword = 'white'
)
GROUP BY a.data_id
HAVING COUNT( a.data_id ) =4 

Сначала без индексов я получил следующие результаты:

enter image description here

Затем, с индексом data_id и keyword_id, я получил это:

enter image description here

Итак, насколько я понимаю, количество строк, которые MySQL должен искать, увеличивается с 61 до 10 тыс.что должно быть хорошо, верно?

Итак, мой вопрос, я прав здесь?И есть ли что-то еще, о чем я мог подумать, пытаясь оптимизировать?

ОБНОВЛЕНИЕ:

Далее, после некоторой помощи от AJ и Писквор, указывая на мою другую таблицу иКлючевое слово его столбца без индекса Я получил это:

enter image description here

Большое улучшение!Правильно?

Ответы [ 6 ]

4 голосов
/ 19 апреля 2011

Как видите, key для таблицы b по-прежнему NULL.Возможно, вы захотите добавить индекс на b.keyword и сопоставить с

WHERE b.keyword IN ('dog','black','and','white')

. Это функционально отличается от вашего предложения WHERE, хотя и возвращает те же результаты.

Как это выглядитВы можете быть заинтересованы в полнотекстовом поиске.

3 голосов
/ 19 апреля 2011

В зависимости от того, чего вы хотите достичь, вам следует либо заменить LEFT JOIN на INNER JOIN, либо переместить условие WHERE в предложение ON:

Как сейчас:

SELECT  a.*
FROM    `tff__keywords2data` AS a
LEFT JOIN
        `tff__keywords` AS b
ON      b.id = a.keyword_id
WHERE   b.keyword = 'dog' || b.keyword = 'black' || b.keyword = 'and' || b.keyword = 'white'
GROUP BY
        a.data_id
HAVING  COUNT( a.data_id ) = 4 

Ваш запрос фактически является соединением INNER (поскольку в предложении WHERE имеются ненулевые условия).

Кроме того, вместо использования битовой арифметики (которая не может быть sargable) вы должны использовать собственные конструкции OR или IN:

SELECT  a.*
FROM    `tff__keywords2data` AS a
JOIN    `tff__keywords` AS b
ON      b.id = a.keyword_id
WHERE   b.keyword IN ('dog', 'black', 'and', 'white')
GROUP BY
        a.data_id
HAVING  COUNT(*) = 4 

Вы также можете создать индекс на ttf__keywords (keyword), который может фильтровать на keywords, который вы ищете, и делать меньше записей для выбора из ведущих b.

Наконец, если вам не нужно неявное упорядочение a.data_id, избавьтесь от него, добавив ORDER BY NULL:

SELECT  a.*
FROM    `tff__keywords2data` AS a
JOIN    `tff__keywords` AS b
ON      b.id = a.keyword_id
WHERE   b.keyword IN ('dog', 'black', 'and', 'white')
GROUP BY
        a.data_id
HAVING  COUNT(*) = 4 
ORDER BY
        NULL

Это удалит filesort из вашего плана.

1 голос
/ 19 апреля 2011

Попробуйте поместить индексы для всего в предложении WHERE и всего в JOIN, так что это будет:

a.keyword_id b.id b.keyword

Вы также можетепопробуйте добавить индекс в a.data_id, как в «GROUP BY».Слишком много индексов обычно не является проблемой, если только вы не добавляете большие объемы данных в большие таблицы - это может привести к очень медленной вставке.

1 голос
/ 19 апреля 2011

Используйте INNER JOIN вместо LEFT JOIN. Левое соединение вернет несопоставленные строки в таблице соединений, которые, я думаю, вам здесь не нужны.

1 голос
/ 19 апреля 2011

Вы проводите сравнение строк с b.keyword .... добавьте туда индекс.

1 голос
/ 19 апреля 2011

Да, это улучшилось (но от быстрого поиска я думаю, что может быть улучшено).вы можете видеть, что оптимизатор запросов теперь видит И ИСПОЛЬЗУЕТ индекс keyword_id.он уменьшил число строк, которые он ищет, с 64283 до 10216. но он все еще использует файловую сортировку, которая, надеюсь, кто-то еще может уточнить, похожа на сканирование таблицы SQL Server?что нехорошо ... хотя я могу ошибаться.

Теперь вы сможете уменьшить количество строк в таблице b ниже 10216

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...