MySQL оптимизация запросов - PullRequest
       8

MySQL оптимизация запросов

0 голосов
/ 07 декабря 2009

У меня есть эта база данных:

Tab1 --- 1: n ---> tab2 (parent-> id) (max1: 4) - сложная часть

Tab1 --- 1: n ---> tab3 (parent-> id) - простое объединение

tab1

ID
Имя
версия
..так далее.

tab2

ID
Родитель
тип
цена
..так далее.

tab3

ID
Родитель
тип
данные

Я бы хотел выбрать полный набор информации из этих трех объединенных таблиц, но мне нужно использовать множество переменных условий, поэтому мне нужно найти наилучшее решение, насколько это возможно.

Я использую этот запрос:

SELECT tab1.id, CONCAT(tab1.name,' ',tab1.version) AS nv, ndvar.price, tab3.data,
ndvar.v1  
[more columns] 
FROM tab1 INNER JOIN ( 
SELECT parent, 
type, 
GROUP_CONCAT(type SEPARATOR '') + '' AS v1,  
MIN(price) AS price  
[more columns]  
FROM tab2  
WHERE show = 1  
[more condition]  
GROUP BY parent  
HAVING type IN (2,3) [1-3 parameters]  
)  
AS ndvar  
ON tab1.id = ndvar.parent  
LEFT JOIN content  
ON tab1.id = tab3.parent AND tab3.type = 0   
WHERE name LIKE '%xyz%'  
[more conditions]  
ORDER BY nv  

Я пытался сделать его настолько простым, чтобы понять, как мог.

Мои вопросы: 1) Как оптимизировать этот запрос, чтобы как можно быстрее 2) Какие столбцы используют в качестве индексов? Пока это только столбец id.

Столбец 'type' в tab2 содержит значения 0-3, и для каждого идентификатора есть только строка с этим типом, поэтому есть связь по индексу, но я не знаю, улучшит ли это мой запрос.

Заранее спасибо.

EDIT:

Это запрос, используемый при поиске в онлайн-каталоге, в течение месяца будет только несколько вставок или обновлений, но каждый день будет выполняться много запросов. В tab1 будет около сотни записей, tab2 вокруг tab1 * 4 записей и tab3 вокруг tab1 * 15 записей. Существует много условий поиска, включающих в основном tab1 (1-15 параметров) и tab2 для 3 параметров. Все параметры являются числами (двойными), кроме имени и версии, которые являются именем - varchar (25) и версией - varchar (20).

Запрос будет выполнен на mysql 5.0.70, db engine MyISAM

По всей имеющейся у меня статистике, поиск для tab2.price range и tab2.type является наиболее распространенным, а поиск для других диапазонов номеров встречается чаще, чем поиск по tab1.name или tab1.version.

Я с удовольствием заполню любую другую информацию, которую кто-нибудь спросит.

Кстати: извините за плохую грамматику, английский не мой родной язык:)

EDIT2:

Я мог бы неверно истолковать всю концепцию «ИМЕЕТ». В v1 мне нужно было сохранить весь набор значений из строк tab2 для каждого родителя из tab1, но мне нужно отфильтровать их по tab2.type .. как это сделать?

EDIT3:

Этот тип агрегации возвращает именно то, что мне нужно, НО - я знаю его ужасное решение, кто-то знает, как его улучшить?

 GROUP BY parent 
 HAVING v1 LIKE  '%0%

1 Ответ

0 голосов
/ 07 декабря 2009

Tab2.type и tab1.id, tab2.parent и tab3.parent, вероятно, являются наиболее важными строками, для которых есть индексы, если они идентифицируют очень специфические строки.

Что касается индексов, другие, которые могут помочь, это tab2.price, tab3.type.

Как правило, чем больше строк должно исключать условие из результатов, тем хуже ему нужен индекс.

"WHERE name LIKE"% stuff% ', вероятно, является одним из худших условий в мире (хотя и одним из самых распространенных), потому что обычные индексы ничего не делают. Если этот тест удаляет много строк из результат (имеется в виду, что он тестирует много строк и мало проходит условие), тогда вам следует использовать полнотекстовый индекс.

Подвыбор после внутреннего объединения может быть скачком производительности, так как он должен независимо формировать набор результатов.

...