Mysql 优化SQL查询
我正在尝试优化这个缓慢的查询(>2s) 这是我使用EXPLAIN时的输出:Mysql 优化SQL查询,mysql,join,Mysql,Join,我正在尝试优化这个缓慢的查询(>2s) 这是我使用EXPLAIN时的输出: id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE c index_merge PRIMARY,crmentity_smownerid_idx,crmentity_deleted_smownerid_idx,crmentity_smownerid_deleted_idx crmenti
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE c index_merge PRIMARY,crmentity_smownerid_idx,crmentity_deleted_smownerid_idx,crmentity_smownerid_deleted_idx crmentity_smownerid_idx,crmentity_deleted_smownerid_idx 4,8 NULL 91 Using intersect(crmentity_smownerid_idx,crmentity_deleted_smownerid_idx); Using where; Using index
1 SIMPLE mt ref activityid activityid 4 pharex.c.crmid 60
1 SIMPLE mtu ref dept_idx dept_idx 5 const 1530 Using where
它使用的是我创建的索引(dept_idx),但对1380384条记录的数据集运行查询仍然需要2秒钟以上。是否有另一种以最佳方式表达此查询的方法
更新:根据David的建议,查询现在只需几毫秒,而不是运行超过2秒(实际上,MySQL 5.0版的查询时间为51秒)
WHERE
子句中最有选择性的部分是什么?也就是说,哪个条件会从结果集中删除最有潜力的项
我猜这是mtu.ts
过滤器。如果这是真的,您还应该为mtu.ts
列编制索引,并尝试以可以使用索引的方式对此进行约束;例如,使用运算符
其他提示:
- 使用
,这使得查询更易于阅读,无论是对于人还是优化器join将join子句直接附加到join。。。在()上
- 避免在查询中计算常量,如
YEAR(NOW())
- 避免WHERE子句中所选列的函数,如
。这降低了大量使用索引的可能性MONTH(mtu.ts)
- 规范化您的数据,以避免出现诸如mtu.dept='GUN'或mtu.dept='GUN'之类的套管问题。;一个
和一个适当的更新mtu设置dept=lower(dept)
将有助于避免这种疯狂检查dept=lower(dept)
这可能会使您的查询速度大大加快,因为您将限制需要进行日期比较的数据量。我会编写
其中lower(mtu.dept)=“gun”和…
,但我认为您的数据库已经以这种方式对其进行了优化。我发现,至少在Oracle中,在查询的左侧使用lower会导致速度大幅降低。无论它是否比额外的字符串比较更慢……对列使用lower()是一种不使用任何索引的好方法。这可以解释你的慢下来。格雷厄姆,大卫,你当然是对的。我不会删除我的注释,这样反模式仍然有效;-)贴得太快了,基本上就是大卫·施密特和伯纳尔所说的!你会怎么重写这个?再次感谢。请从c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.cc.deleted=0和c.smownerid=28谢谢这个例子。我在PHP中创建了一个函数来获取月份的开始日期和结束日期,并在“BETWEEN”语句中使用它。
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE c index_merge PRIMARY,crmentity_smownerid_idx,crmentity_deleted_smownerid_idx,crmentity_smownerid_deleted_idx crmentity_smownerid_idx,crmentity_deleted_smownerid_idx 4,8 NULL 91 Using intersect(crmentity_smownerid_idx,crmentity_deleted_smownerid_idx); Using where; Using index
1 SIMPLE mt ref activityid activityid 4 pharex.c.crmid 60
1 SIMPLE mtu ref dept_idx dept_idx 5 const 1530 Using where