我需要幫助來優化此查詢。在連接查詢中優化按子句的順序
SELECT messages.*
FROM messages
INNER JOIN subscription ON subscription.entity_id = messages.entity_id
WHERE subscription.user_id = 1
ORDER BY messages.timestamp DESC
LIMIT 50
沒有限制,該查詢返回200K行,大約需要1.3-2秒才能運行。這個問題似乎是按照從句的順序。沒有它,查詢需要.0005秒。
Indexes:
(subscription.user_id, subscription.entity_id)
(subscription.entity_id)
(messages.timestamp)
(messages.entity_id, messages.timestamp)
我能夠通過改變查詢此以提高性能:
SELECT messages.* FROM messages
INNER JOIN subscription ON subscription.entity_id = messages.entity_id
INNER JOIN (
SELECT message_id FROM messages ORDER BY timestamp DESC
) as temp on temp.messsage_id = messages.message_id
WHERE subscription.user_id = 1 LIMIT 50
這個運行在0.12秒。一個非常好的改進,但我想知道它是否會更好。它似乎 如果我能以某種方式篩選第二個內部聯接,那麼事情會更快。
謝謝。
架構:
messages
message_id, entity_id, message, timestamp
subscription
user_id, entity_id
UPDATE
雷蒙德Nijland的回答解決了我最初的問題,但另一隻冒出了
SELECT messages.*
FROM messages
STRAIGHT_JOIN subscription ON subscription.entity_id = messages.entity_id
WHERE subscription.user_id = 1
ORDER BY messages.timestamp DESC
LIMIT 50
直連接是在兩種情況下效率低:
沒有在認購表中沒有的user_id進入
有郵件表
關於如何解決此問題的任何建議一些相關的條目?如果不是從查詢的角度來看,應用程序呢?
UPDATE
EXPLAIN信息
LIMIT 50
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
| 1 | SIMPLE | messages | index | idx_timestamp | idx_timestamp | 4 | NULL | 50 | |
| 1 | SIMPLE | subscription | eq_ref | PRIMARY,entity_id,user_id | PRIMARY | 16 | const, messages.entity_id | 1 | Using index |
無極限
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
| 1 | SIMPLE | messages | ALL | entity_id_2,entity_id | NULL | NULL | NUL | 255069 | Using filesort|
| 1 | SIMPLE | subscription | eq_ref | PRIMARY,entity_id,user_id | PRIMARY | 16 | const, messages.entity_id | 1 | Using index |
CREATE TABLE語句:
個隨着〜5000行
subscription | CREATE TABLE `subscription` (
`user_id` bigint(20) unsigned NOT NULL,
`entity_id` bigint(20) unsigned NOT NULL,
PRIMARY KEY (`user_id`,`entity_id`),
KEY `entity_id` (`entity_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
與〜255,000行
messages | CREATE TABLE `messages` (
`message_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`entity_id` bigint(20) unsigned NOT NULL,
`message` varchar(255) NOT NULL DEFAULT '',
`timestamp` int(10) unsigned NOT NULL,
PRIMARY KEY (`message_id`),
KEY `entity_id` (`entity_id`,`timestamp`),
KEY `idx_timestamp` (`timestamp`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
您可以發佈展會CREATE TABLE語句? –
單個用戶200,000行?你確定嗎? –
@DanBracuk是的,我相信 –