2013-07-13 2 views
0
SELECT 
    n.id, 
    n.title, 
    n.text, 
    n.date, 
    IFNULL(ap.name, a.name) AS name, 
    IFNULL(ap.path, a.path) AS path, 
    IFNULL(ap.extension, a.extension) AS extension, 
    IFNULL(ap.width, a.width) AS width, 
    IFNULL(ap.height, a.height) AS height, 
    IFNULL(ap.server, a.server) AS server, 
    s.id AS source_id, 
    s.name AS source_name 
FROM news n 
LEFT JOIN news_attachments na ON n.id = na.news_id AND na.cover = 1 
LEFT JOIN attachments a ON na.attachments_id = a.id 
LEFT JOIN attachments ap ON a.id = ap.parent AND ap.width = 136 
JOIN sources s ON n.sources_id = s.id 
WHERE n.moderate = 1 AND n.delete = 0 
GROUP BY n.id 
ORDER BY n.date DESC 
LIMIT 25 

У меня есть этот SQL-запрос. И у меня вопрос, хорошо это или нет? Может быть, я могу это улучшить?Оптимизируйте мой длинный запрос mysql

В этой части

LEFT JOIN attachments a ON na.attachments_id = a.id 
LEFT JOIN attachments ap ON a.id = ap.parent AND ap.width = 136 

загружаю предварительный просмотр изображения, а затем в выберите:

IFNULL(ap.name, a.name) AS name, 
    IFNULL(ap.path, a.path) AS path, 
    IFNULL(ap.extension, a.extension) AS extension, 
    IFNULL(ap.width, a.width) AS width, 
    IFNULL(ap.height, a.height) AS height, 
    IFNULL(ap.server, a.server) AS server 

Это значит, если он имеет предварительный просмотр изображения, а затем использовать его иным образом использовать исходное изображение

EXPLAIN:

+----+-------------+-------+--------+-------------------------------------------+----------------------+---------+--------------------------+------+---------------------------------+ 
| id | select_type | table | type | possible_keys        | key     | key_len | ref      | rows | Extra       | 
+----+-------------+-------+--------+-------------------------------------------+----------------------+---------+--------------------------+------+---------------------------------+ 
| 1 | SIMPLE  | s  | ALL | PRIMARY,id        | NULL     | NULL | NULL      | 4 | Using temporary; Using filesort | 
| 1 | SIMPLE  | n  | ref | fk_news_sources1_idx      | fk_news_sources1_idx | 4  | base.s.id    | 93 | Using where      | 
| 1 | SIMPLE  | na | ref | PRIMARY,fk_news_has_attachments_news1_idx | PRIMARY    | 4  | base.n.id    | 1 |         | 
| 1 | SIMPLE  | a  | eq_ref | PRIMARY,id        | PRIMARY    | 4  | base.na.attachments_id | 1 |         | 
| 1 | SIMPLE  | ap | ALL | NULL          | NULL     | NULL | NULL      | 3720 |         | 
+----+-------------+-------+--------+-------------------------------------------+----------------------+---------+--------------------------+------+---------------------------------+ 
+2

что объясняет сказать? – exussum

+1

Я не слишком хорош в оптимизации, но я бы попытался приклеить сложный индекс (родительский, ширина) в таблице вложений. – Strawberry

+0

Итак, этот запрос * slow * (и что для вас медленнее) или просто * long *? – fvu

ответ

1

Предполагая, что все news записи имеет sources, попробуйте добавить индекс к новостям на moderate, delete и date (в таком порядке), а затем попробуйте следующий запрос:

SELECT 
    n.id, 
    n.title, 
    n.text, 
    n.date, 
    IFNULL(ap.name, a.name) AS name, 
    IFNULL(ap.path, a.path) AS path, 
    IFNULL(ap.extension, a.extension) AS extension, 
    IFNULL(ap.width, a.width) AS width, 
    IFNULL(ap.height, a.height) AS height, 
    IFNULL(ap.server, a.server) AS server, 
    s.id AS source_id, 
    s.name AS source_name 
FROM (select * 
     from news 
     WHERE moderate = 1 AND delete = 0 
     ORDER BY date DESC 
     LIMIT 25) n 
LEFT JOIN news_attachments na ON n.id = na.news_id AND na.cover = 1 
LEFT JOIN attachments a ON na.attachments_id = a.id 
LEFT JOIN attachments ap ON a.id = ap.parent AND ap.width = 136 
JOIN sources s ON n.sources_id = s.id 
GROUP BY n.id 
+1

Я также добавил ORDER BY n.date DESC в конце, потому что он показывает результаты на каблуках – user2058653

1

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

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

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

+0

Нет, источники около 4 сейчас и будут максимальными 20-30. Но спасибо за ваш ответ, это очень полезно. – user2058653

+0

Ой, извините, это неправильно. Предположим, что будет больше новостей, чем источников, поэтому почему он взял источники и присоединился к новостям. – Kickstart

Смежные вопросы