У меня есть структура, которая генерирует SQL. один из запросов использует мой индекс "А" и возвращает результаты за 7 секунд. Я вижу, что я могу оптимизировать это, и я создал индекс "B".
теперь, если я запустил "объяснить мой запрос", он все равно использует мой индекс A. Однако, если я заставляю использовать индекс B, я получаю свои результаты за 1 секунду (7 раз быстрее)
поэтому мой индекс B быстрее, чем мой индекс A. Я не могу использовать команду "индекс силы" или "использовать индекс", поскольку мой sql генерируется из фреймворка, который этого не поддерживает.
Итак, почему mysql естественно не использует самый быстрый индекс. И есть способ, которым я могу сказать, что mysql всегда использует определенный индекс без добавления "использования" или "силы".
запрос:
SELECT *
FROM soumission
LEFT OUTER JOIN region_administrative
ON soumission.region_administrative_oid=region_administrative.oid
WHERE (soumission.statut=2
AND ((soumission.telephone LIKE '%007195155134070067132211046052045128049212213255%'
OR (soumission.autre_telephone LIKE '%007195155134070067132211046052045128049212213255%'))
OR (soumission.cellulaire LIKE '%007195155134070067132211046052045128049212213255%')))
ORDER BY soumission.date_confirmation DESC, soumission.numero;
я добавил индекс для нескольких столбцов "statut", "phone", "autre_telephone", "cellulaire"
если я использую этот индекс, мой запрос будет 7 раз быстрее, но если я не укажу, какой индекс использовать, он использует другой индекс (только в поле statut), который на 7x медленнее
вот объяснение, если я выбираю большой период времени (используя неправильный индекс)
здесь, когда я выбираю небольшое окно даты
Что касается самого запроса:
Итак, создайте эти индексы:
ALTER TABLE 'region_administrative' ADD INDEX 'region_administrativ_idx_oid' ('oid');
ALTER TABLE 'soumission' ADD INDEX 'soumission_idx_statut_oid_cellulaire' ('statut','region_administrative_oid','cellulaire');
ALTER TABLE 'soumission' ADD INDEX 'soumission_idx_statut_oid_telephone' ('statut','region_administrative_oid','autre_telephone');
ALTER TABLE 'soumission' ADD INDEX 'soumission_idx_statut_oid_telephone' ('statut','region_administrative_oid','telephone');
Затем попробуйте выполнить этот запрос:
SELECT
*
FROM
((SELECT
*
FROM
soumission
LEFT OUTER JOIN
region_administrative
ON soumission.region_administrative_oid = region_administrative.oid
WHERE
(
soumission.statut = 2
AND (
(
soumission.cellulaire LIKE '007195155134070067132211046052045128049212213255%'
)
)
)
ORDER BY
soumission.date_confirmation DESC,
soumission.numero)
UNION
DISTINCT (SELECT
*
FROM
soumission
LEFT OUTER JOIN
region_administrative
ON soumission.region_administrative_oid = region_administrative.oid
WHERE
(soumission.statut = 2
AND (((soumission.autre_telephone LIKE '007195155134070067132211046052045128049212213255%'))))
ORDER BY
soumission.date_confirmation DESC,
soumission.numero)
UNION
DISTINCT (SELECT
*
FROM
soumission
LEFT OUTER JOIN
region_administrative
ON soumission.region_administrative_oid = region_administrative.oid
WHERE
(soumission.statut = 2
AND ((soumission.telephone LIKE '007195155134070067132211046052045128049212213255%')))
ORDER BY
soumission.date_confirmation DESC,
soumission.numero)
) AS union1
ORDER BY
union1.date_confirmation DESC,
union1.numero
Кажется, это то, что вы делаете...
SELECT s.*, ra.*
FROM soumission AS s
LEFT OUTER JOIN region_administrative AS ra ON s.region_administrative_oid=ra.oid
WHERE s.statut = 2
AND ( s.telephone LIKE '%007195155134070067132211046052045128049212213255%'
OR s.autre_telephone LIKE '%007195155134070067132211046052045128049212213255%'
OR s.cellulaire LIKE '%007195155134070067132211046052045128049212213255%'
)
ORDER BY s.date_confirmation DESC, s.numero;
Если вам не нужен ra.*
, Избавьтесь от LEFT JOIN
.
Предлагаемый многоколоновый индекс бесполезен и не будет использоваться, если... statut = 2
менее 20% строк. В этом случае он будет использовать только первый столбец индекса.
OR
поражает индексирование. (Увидеть ниже)
Ведущий подстановочный знак для индексации поражений LIKE
. Вам нужны ведущие или задние дикие карты?
Смешение DESC
и ASC
в ORDER BY
поражает, используя индекс, чтобы избежать сортировки.
Так что делать? Вместо трех столбцов для ровно 3 телефонных номеров, у вас есть другая таблица для телефонных номеров. Затем у вас есть любое количество строк для данного приема. Тогда поиск этой таблицы может быть более быстрым из-за исключения OR
- но только если вы избавитесь от основной подстановки.
(Это ужасно длинный номер телефона! Это правда?)