缓慢的MySQL SELECT查询
我有一个缓慢的MySQL SELECT查询,我似乎无法排除故障。缓慢的MySQL SELECT查询
这是一个简单的,在大约600,000条记录的表上。
SELECT *
FROM `civicrm_contact` contact
WHERE contact.external_identifier =123456
SELECT查询需要之间的任何地方3-6秒,这使导入另一个60万点的记录依赖于该查询,完全不切实际。
的表索引示于附加的图像:
如果我搜索基于contact.id = 123456则查询时间下降到约0.004s。 contact.id是表格上的主键。 external_identifier是唯一的索引。
看来你使用BTREE
索引。如果您未对此列执行任何范围查询(使用<
,>
,<=
或>=
),则可能需要使用基于散列的索引。
有关详细信息,请参见Comparison of B-Tree and Hash Indexes。
并参见here确切的语法。
我改变了结构,使INT类型的external_identifier而不是VARCHAR。速度已经提高到0.006s
我还没有确定这是否将有任何更广泛的影响
我知道这是一个古老的线程,但由于涉及到CiviCRM我想我会推我的想法。该修复实际上并不是最佳实践,因为您已更改了核心打包表之一,以加快查询的运行速度。虽然这可能对你有好处,但我绝对不会向每个人推荐这个。
虽然您的解决方案可能突出显示了查询的问题,但您似乎在告诉查询,您希望得到一个数字,但事实上数据存储为VARCHAR。所以我认为只要在价值中加上单引号就可以做到这一点。
SELECT * FROM 接触civicrm_contact
WHERE = contact.external_identifier“123456”
没有这个我敢肯定(已与Oracle工作了数年),一个隐式数据类型转换会发生因此查询不能使用INDEX。
解释计划应该证明这个理论。
感谢
帕尔韦兹
我半信半疑的数据类型转换为这个问题的。我想知道这是否与索引字段的大小限制有关。作为一个btree意味着索引键可能比散列键要大得多。这是必要的吗?将外部ID保存在一个单独的表中并将它们基于数字ID链接起来会更好吗?
更多的问题比这里的答案真的。
你绝对需要'select *'吗? – nico 2012-04-23 16:23:36
不 - 我只是通过将其限制为SELECT id来测试它,但查询仍在1.5到2秒之间。所以它更好,但仍然太慢。 – bpmccain 2012-04-23 16:29:27
我正在7.5GB Amazon EC2大型实例上运行它。总数据库大小约为1GB,因此有大量内存。 – bpmccain 2012-04-23 16:33:17