2015-01-23 1 views
2

У нас есть запрос на 30 секунд. Когда мы убираем этот HAVING условия, это занимает 1 секунду:Как ускорить HAVING, который использует LIKE% ...%

HAVING (group_concat(DISTINCT service.service ORDER BY 
service.service ASC SEPARATOR ",") like "%translation%") 
ORDER by fqa_value DESC 
LIMIT 0,10; 

Поля service.service является ENUM с одним из пунктов «перевод».

Есть ли более эффективный способ построить это HAVING без создания строки, разделенных запятыми, а затем искать в нем в виде текста, что-то вроде этого:

HAVING ("translation" IN (DISTINCT service.service ORDER BY service.service)) 
ORDER by fqa_value DESC 
LIMIT 0,10; 
+1

Вы можете дать полный sql. – Nick

+1

Любые улучшения, если вы удаляете отдельные и/или заказываете? – Mihai

+0

Я подозреваю, что 'DISTINCT' и' ORDER BY' - это то, как агрегат вызывается в 'SELECT', а то, что используется в предложении' HAVING', должно быть одинаковым. –

ответ

0

С вашего LIKE начинается с группового символа вы находитесь что-то принципиально изменит ваш подход. MySQL не может индексировать данные, когда вы выполняете полнотекстовый поиск.

Если вы можете изменить таблицу:

Разбить перечислимую в BOOL-столбцов (один для каждого возможного значения перечислений) и индекс их. Это единственный способ, которым вы будете быстрее, чем O (n).

+1

Вам не хватает того факта, что это предложение 'HAVING', которое я думаю? Даже если это было 'HAVING indexedcolumn = 1', оно все равно игнорировало бы ваш индекс, поскольку это не 'WHERE', поэтому он запускается впоследствии? – Nanne

0

«перевод» IN (DISTINCT service.service ORDER BY service.service) «DISTINCT» и «ORDER BY» не являются relavent и должны быть отброшены.

Я сделал что-то похожее на то, что вы пытаетесь, но я создал дополнительное поле и застрял в нем все поля поиска, а затем выполнил поиск этого поля.

Вам придется вернуться назад и изменить (добавить в избранное) ваши таблицы, написать триггер, но он должен сделать трюк для вас

0

Вы можете обнаружить, что вы получите лучшую производительность, если вы удалите предложения HAVING, и вместо этого добавьте еще один соединитесь (под другим псевдонимом) с таблицей служб с существующими критериями соединения с дополнительным критерием service = "translation".

1

FYI, есть логическая ошибка в этом HAVING пункте:

HAVING (group_concat(DISTINCT service.service ORDER BY service.service ASC SEPARATOR ",") like "%translation%") 

Это будет соответствовать вещам, как atranslation, btranslation и т.д., потому что вы явно не соответствующим стартовой запятой. Вы хотите что-то больше, как это (скобки вокруг пункта являются лишними):

HAVING CONCAT(',', group_concat(DISTINCT service.service ORDER BY service.service ASC SEPARATOR ","), ',') like "%,translation,%" 

или это:

HAVING 'translation' REGEXP CONCAT('^(', group_concat(DISTINCT service.service ORDER BY service.service ASC SEPARATOR '|'), ')$') 

Однако, я не думаю, что любой из тех, кто поможет значительно производительность. Вместо того, что вы могли бы сделать это следующим образом:

SELECT mykeycolumn, fqa_value, GROUP_CONCAT(DISTINCT service.service ORDER BY service.service ASC SEPARATOR ",") 
    FROM service s1 
WHERE EXISTS (SELECT 1 FROM service s2 
       WHERE s2.mykeycolumn = s1.mykeycolumn 
        AND s2.service = 'translation') 
ORDER BY fqa_value DESC 
LIMIT 0,10; 

где mykeycolumn ваш столбец первичного ключа или столбцов.