我们的服务器公司建议我们在设置新的数据库服务器时切换到Percona。因此,我们目前正在使用Percona服务器(GPL),版本82.0(版本5.6.36-82.0),修订版58e846a以及我试图解决的一个行为,我们肯定没有&以前用MySql体验过,所以我想我会伸手去拿:
这是我们定期执行的查询,用于从我们的数据库中提取文章
SELECT * FROM table_a a,table_b b WHERE a.id = b.id AND a.status_field =' open' AND b.filter_field =' no_filter'和b.view_field ='文章' ORDER BY a.unixtimestamp DESC LIMIT 1
这用来很快完成但是在Percona下,表b中where条件和表a中的排序的组合使得整个查询需要~3s。我不完全理解这种行为。
如果我改为:
SELECT * FROM table_a a,table_b b WHERE a.id = b.id AND a.status_field =' open' AND b.filter_field =' no_filter'和b.view_field ='文章' ORDER BY b.unixtimestamp DESC LIMIT 1
然后它很快完成(<0.05s)
这是Percona的预期行为吗?
我只是想在更改任何db结构之前知道以进行补偿。
为了解释,我简化了查询,它仍然有相同的问题(id = entry_id):
慢查询(1.5122389793):
SELECT * FROM table_a a,table_b b WHERE a.id = b.id AND b.special_filter =&#39; no_filter&#39; 按顺序排列DESC限制1
慢查询解释:
1 SIMPLE table_b ref PRIMARY,entry_id,special_filter special_filter 26 const 130733使用where;使用临时;使用filesort 1 SIMPLE table_a eq_ref PRIMARY PRIMARY 4 db_name.table_b.entry_id 1使用索引
快速查询(0.0006549358):
SELECT * FROM table_a a,table_b b WHERE a.id = b.id AND b.special_filter =&#39; no_filter&#39; ORDER BY b.id DESC LIMIT 1
快速查询说明: 1 SIMPLE table_b ref PRIMARY,entry_id,special_filter special_filter 26 const 130733使用where 1 SIMPLE table_a eq_ref PRIMARY PRIMARY 4 db_name.table_b.entry_id 1使用索引
出于安全原因,我试图尽可能多地从表格中删除信息,但如果我遗漏了一些东西,我可以将其添加回来
table_a:
相关密钥:
table_a 0 PRIMARY 1 entry_id A 321147 BTREE
创建表格:
table_a CREATE TABLE table_a
(entry_id
int(10)unsigned NOT NULL AUTO_INCREMENT)ENGINE = InnoDB AUTO_INCREMENT = 356198 DEFAULT CHARSET = utf8 DELAY_KEY_WRITE = 1
table_b:
相关密钥:
table_b 0 PRIMARY 1 entry_id A 261467 BTREE
table_b 1 entry_id 1 entry_id A 261467 BTREE
table_b 1 special_filter 1 special_filter A 14 8 BTREE
创建表格:
table_b CREATE TABLE table_b
(entry_id
int(10)unsigned NOT NULL DEFAULT&#39; 0&#39;,special_filter
text NOT NULL,)ENGINE = InnoDB DEFAULT CHARSET = utf8 DELAY_KEY_WRITE = 1
两个表都有~350k行
答案 0 :(得分:0)
它似乎是一个mysql优化器问题,它选择在某些条件下不加入主键。与此问题密切相关或相同:https://dba.stackexchange.com/questions/53274/mysql-innodb-issue-not-using-indexes-correctly-percona-5-6
明确地编写查询以使用STRAIGHT_JOIN以特定顺序的表来解决问题。在JOIN关键字之后编写USE INDEX(PRIMARY)虽然更容易,但并不依赖于表顺序。