Выборка из (modTemplateVarResource): существенное ускорение при явном указании индекса
Возьмём простой запрос на выборку идентификаторов ресурсов из таблицы (modTemplateVarResource):
SELECT DISTINCT modTemplateVarResource.contentid AS id
FROM `modx_site_tmplvar_contentvalues` AS `modTemplateVarResource`
WHERE (modTemplateVarResource.tmplvarid = 195) AND (modTemplateVarResource.value IN ('11326','19495','12813','20181','12693','12993','11327'))
Запрос выполняется 0.0151 сек
План запроса:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE modTemplateVarResource ref tmplvarid,tv_cnt tv_cnt 4 const 6156 Using where
Далее добавляем в таблицу (modTemplateVarResource) 4 отсутствующих индекса:
ALTER TABLE `modx_site_tmplvar_contentvalues` ADD INDEX `idx_value` ( `value` ( 20 ) )
ALTER TABLE `modx_site_tmplvar_contentvalues` ADD INDEX `idx_tv_value` ( `tmplvarid` , `value` ( 20 ) )
ALTER TABLE `modx_site_tmplvar_contentvalues` ADD INDEX `idx_value_tv` ( `value` ( 20 ), `tmplvarid` )
ALTER TABLE `modx_site_tmplvar_contentvalues` ADD INDEX `idx_content_tv` ( `content`, `tmplvarid` )
Индекс (tv — content) изначально уже имеется (tv_cnt)
Снова запускаем тот же запрос: 0.0038 сек
План запроса (используется индекс idx_value_tv):
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE modTemplateVarResource range tmplvarid,tv_cnt,idx_tv_value,idx_value_tv idx_value_tv 66 NULL 60 Using where; Using temporary
Далее непосредственно указываем серверу использовать индекс idx_value_tv:
SELECT DISTINCT modTemplateVarResource.contentid AS id
FROM `modx_site_tmplvar_contentvalues` AS `modTemplateVarResource` USE INDEX (idx_value_tv)
WHERE (modTemplateVarResource.tmplvarid = 195) AND (modTemplateVarResource.value IN ('11326','19495','12813','20181','12693','12993','11327'))
Получаем: 0.0027 сек. При этом план запроса тот же самый:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE modTemplateVarResource range idx_value_tv idx_value_tv 66 NULL 60 Using where; Using temporary
===============
Почему, в таблице (modTemplateVarResource) изначально нет нужных индексов, задавать не буду — судя по всему, при работе в modx исключительно на уровне xpdo-объектов другие индексы (кроме тех, что имеются «в коробке»), и не нужны.
Вопрос такой: почему при явном указании того же самого индекса запрос работает существенно быстрее. Не чуть быстрее, а существенно быстрее. А ведь запросов при загрузке веб-страницы выполняется куча. И все они могли бы работать гораздо быстрее…
P.S. Если выборку выполнять из таблицы ресурсов, а tv подключать через JOIN и фильтровать так, как приведено здесь (запросы составляются на уровне xpdo, но чистый SQL получается таким как в сабже), то получаем полностью идентичные планы запросов (в части сабжевой фильтрации) и полностью идентичные наблюдения со скоростью их выполнения. На реальных запросах скорость выполнения ощутима.