我有两张桌子:
| users_transactions | CREATE TABLE
users_transactions
(user_id
int(11)NOT NULL,transaction_id
int(11)NOT NULL, 独特的钥匙user_id_transaction_id_unique
(user_id
,transaction_id
) )ENGINE = InnoDB DEFAULT CHARSET = utf8 ||交易| CREATE TABLE
transactions
(id
int(11)NOT NULL AUTO_INCREMENT,name
varchar(45)DEFAULT NULL,transaction_date
datetime DEFAULT NULL, PRIMARY KEY(id
), KEYindex_transactions_on_transaction_date
(transaction_date
) )ENGINE = InnoDB AUTO_INCREMENT = 2000000 DEFAULT CHARSET = utf8
我尝试运行此SQL
SELECT `transactions`.`id`, `transactions`.`transaction_date`
FROM `transactions`
INNER JOIN `users_transactions`
ON `transactions`.`id` = `users_transactions`.`transaction_id`
WHERE `users_transactions`.`user_id` = 71720
ORDER BY `transactions`.`transaction_date` DESC
LIMIT 25 OFFSET 0;
用户71720有超过27000个交易,这个SQL将花费> 4S。我试着解释一下,它显示了
*************************** 1. row ***************************
id: 1 select_type: SIMPLE
table: users_transactions
type: ref possible_keys: user_id_transaction_id_unique
key: user_id_transaction_id_unique
key_len: 4
ref: const
rows: 52968 <--- It returns too many rows, bad smell
Extra: Using index; Using temporary; Using file sort
*************************** 2. row ***************************
id: 1 select_type: SIMPLE
table: transactions
type: eq_ref possible_keys: PRIMARY
key: PRIMARY
key_len: 8
ref: NULL
rows: 1
Extra: Using where 2 rows in set (0.00 sec)
表明它没有使用index_transactions_on_transaction_date
。
当我尝试使用STRAIGHT_JOIN
时,它正在使用index_transactions_on_transaction_date
,并在用户71720上快速执行。但对于没有多笔交易的其他用户,STRAIGHT_JOIN
比INNER JOIN
慢得多。
有什么建议吗?
答案 0 :(得分:1)
这是您的查询:
SELECT t.id, t.transaction_date
FROM transactions t INNER JOIN
users_transactions ut
ON t.id = ut.transaction_id
WHERE ut.user_id = 71720
ORDER BY t.transaction_date DESC
LIMIT 25 OFFSET 0;
你遇到一个问题,你有两个不同的执行计划,一个最适合某些数据,一个最适合其他人。我不认为MySQL在处理这个问题上做得很好。
您有什么方法可以将transaction_date
列放入user_transactions
吗?这将使您能够针对这两种情况优化查询。
我建议将其重写为: