2009-05-07 3 views
0

В настоящее время я работаю над веб-сайтом, который нуждается в некоторых оптимизациях ... так как передняя страница занимает около 15-20 секунд для загрузки, я думал, что некоторая оптимизация будет приятной.MySQL Query optimization

Вот один запрос, который появился на MySQL журнал медленных запросов:

SELECT a.user,a.id 
FROM `profil_perso` pp 
INNER JOIN `acces` a ON pp.parrain = a.id 
INNER JOIN `acces` ap ON ap.id = pp.id 
WHERE pp.parrain_visibilite = '1' 
    AND a.actif = 1 
GROUP BY a.id 
ORDER BY ap.depuis DESC LIMIT 15; 

На profil_perso (~ 207K линии - содержит электронную почту и профили) Существует perso_id, что является первичным ключом, есть также id (внешний ключ) + parrain (референт) + parrain_visibilite (показан референт), которые являются индексами.

На acces есть id, что является первичным ключом, есть также Depuis (дата регистрации), который индексируется

Тест показывает, что это на самом деле:

Первый раз: +1,94532990456
Последний раз: +1,94532990456
Среднее время: 0,0389438009262

Я пытался поставить его таким образом:

SELECT DISTINCT a.id, a.user 
FROM `profil_perso` pp 
LEFT JOIN `acces` a ON pp.parrain = a.id 
WHERE pp.parrain_visibilite = 1 
    AND a.actif = 1 
    AND pp.id != 0 
ORDER BY pp.id DESC LIMIT 15; 

Еще тест показать это:

Первый раз: +1,96376991272
Последний раз: +1,96376991272
Среднее время: +0,0393264245987

Любой намек снизить время запроса?

Вот полный индексы:

Вход в помещение:

id (primary) 
derniere_visite -- last visit 
pays_id -- country_id 
depuis -- registration time 
perso_id -- foreign key to profil_perso primary key 
actif -- account status 
compte_premium -- if account is premium 

profil_perso:

perso_id (primary) 
id -- foreign key to acces primary key 
genre -- gender 
parrain_visibilite -- visibility of referer 
parrain -- referer 
parrain_contexte 
telephone 
orientation 
naissance -- birthdate 
photo -- if it has a picture 
+0

Не могли бы вы разместить полные индексы на трех таблицах? Это было бы моим лучшим предположением относительно проблемы, но мне нужно было убедиться, что они будут уверены. – MBCook

+0

Все эти acces.id, acces.ap acces.parrain проиндексированы? – THEn

+0

Это также помогло бы, если бы вы могли объяснить, что вы хотите, чтобы результат был – Greg

ответ

3

Run EXPLAIN SELECT DISTINCT a.id .....;

Это поможет показать вам, где вы могли бы быть пропущены индексы и т.д.

+0

Я соглашаюсь выполнить команду EXPLAIN перед тем, как ваш запрос позволит вам просмотреть запрос для оптимизации. Полезные ссылки http://dev.mysql.com/doc/refman/5.0/ru/using-explain.html http://dev.mysql.com/doc/refman/5.0/ru/explain.html –

+0

Пока вы не знаете, как MySQL запускает ваш запрос, вы можете нанести больше урона, чтобы оптимизировать время выполнения. Использование EXPLAIN создает разбивку того, как MySQL выполняет ваш запрос. –

+0

+1 Запуск EXPLAIN –

0

Почему у вас есть два JOIN?

Создание составного индекса на acces (actif, depuis):

CREATE INDEX ix_acces_actif_depuis ON acces (actif, depuis) 

, создать составной индекс на profil_perso (parrain, parrain_visibilite):

CREATE INDEX ix_profilperso_parrain_parrainvisibilite ON profil_perso (parrain, parrain_visibilite) 

и попробовать это:

SELECT a.user, a.id 
FROM acces a 
JOIN profil_perso p 
ON  pp.parrain = a.id 
     AND pp.parrain_visibilite = 1 
WHERE a.actif = 1 
ORDER BY 
     a.actif DESC, a.depuis DESC 
LIMIT 15 

Этот запрос будет использовать индекс на actif, чтобы избежать сортировки, nd индекс на profil_perso, чтобы найти и отфильтровать невидимые parrain.

Поскольку у вас есть LIMIT 15, этот запрос должен быть мгновенным.

Это также поможет узнать, насколько избирательным является ваше поле actif.

Чтобы понять это, пожалуйста, запустите:

SELECT COUNT(DISTINCT actif)/COUNT(*) 
FROM acces 
+0

Мы рядом. Запрос намного лучше, но у него есть проблема. Запрос генерирует дубликаты (парень может ссылаться на нескольких пользователей ...). Если я добавлю группу по выражению, запрос вернется к 1-2 сек. Использование различий еще хуже. – Erick

+0

Не могли бы вы разместить некоторые данные образца? – Quassnoi

0

Правильный answerr (ы) зависит как от распределения данных (запись отсчетов, мощность полей и комбинации полей и т.д.) Amd схемы , как и в выражении запроса. Даже учитывая эту информацию, мы могли бы предоставить только предложения по тестированию, которые приведут только к дополнительным предложениям для тестирования.

Но мы могли бы начать с первого разреза с помощью схемы таблиц, а также результатов текущего EXPLAIN (выполнить твиз, второй и первый результаты).

0

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

Кроме того, как правило, предпочтительнее иметь определенные индексы для любого поля, на которое вы фильтруете/заказываете - так что, опять же, убедитесь, что они установлены соответствующим образом.

Тем не менее, я думаю, что большая производительность здесь может быть связана с тем, что вы сортируете записи 207 тыс., Чтобы получить последние 15 вставленных - можете ли вы достичь того же по-другому?