【发布时间】:2019-06-25 04:40:27
【问题描述】:
为什么这两个查询的唯一区别是campaign_id(另一个表的外键)得到不同的性能和不同的EXPLAIN结果?
查询 1 - 平均时间:0.21 秒
SELECT tx_time, campaign_id, tx_amount, tx_status FROM tx WHERE
campaign_id=6963 ORDER BY tx_time DESC LIMIT 2500;
查询 2 - 平均时间:0.29 秒
SELECT tx_time, campaign_id, tx_amount, tx_status FROM tx WHERE
campaign_id=6946 ORDER BY tx_time DESC LIMIT 2500;
查询 1 与查询 2 解释:
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 SIMPLE tx NULL index tx_campaign_id tx_time 4 NULL 85591 2.92 Using where
1 SIMPLE tx NULL ref tx_campaign_id tx_campaign_id 4 const 106312 100 Using index condition; Using filesort
更新:在添加 (tx_id,tx_time,campaign_id) 和 (tx_id,tx_time) 索引并运行 ANALYZE 后,查询 1 已提高到 0.15 秒,但查询 2 已减慢到 13 秒。更新的解释:
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 SIMPLE tx NULL index tx_campaign_id tx_time 4 NULL 75450 3.31 Using where
1 SIMPLE tx NULL ref tx_campaign_id tx_campaign_id 4 const 117400 100.00 Using index condition; Using filesort
表交易:
CREATE TABLE
tx(tx_idbigint(20) unsigned NOT NULL AUTO_INCREMENT,tx_timetimestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,campaign_idint(10) unsigned NOT NULL,tx_amountdecimal(12,5) 无符号 NOT NULL,tx_geovarchar(2) NOT NULL,tx_langaugevarchar(511) NOT NULL,tx_uavarchar( 511) 非空,tx_ipvarchar(45) 非空,tx_statustinyint(255) 默认空,
主键 (tx_id),
键tx_campaign_id(campaign_id),
KEYtx_time(tx_time) 使用 BTREE,
KEYtx_amount(tx_amount) 使用 BTREE,
KEYtx_time_campaign_id(tx_id,tx_time,campaign_id) 使用 BTREE,
KEYtx_id_time(tx_id,tx_time) 使用 BTREE,
约束campaign_idcampaign_id外键 (campaign_id) 参考campaign(campaign_id) 删除时不操作更新时不操作
) ENGINE=InnoDB AUTO_INCREMENT=10855433 默认字符集=utf8
【问题讨论】:
-
可能是因为统计信息告诉查询优化器使用不同的索引
-
@RobertKock 是因为可能的总行数 85,591 对 106,312?我应该进行任何更改以进一步优化它吗?
-
我不是数据库专家。我留下我的评论只是因为我认为原因在那个方向的某个地方。我将最终答案留给更专业的人。
-
如果您对 0.08 秒感到担忧,您可以更改查询以强制使用索引命中的索引,例如
SELECT * FROM table1 USE INDEX (col1_index,col2_index)(see documentation)。 -
查询显示一张表;
EXPLAINs显示两个表(实际上是“自连接”)。为什么会出现差异??
标签: mysql sql performance