我的MySQL SELECT查询速度很慢,我似乎无法排除故障。
这是一个简单的,在一张有600,000条记录的桌子上。
SELECT *
FROM `civicrm_contact` contact
WHERE contact.external_identifier =123456
Select查询需要3-6秒之间的任何时间,这使得导入依赖于此查询的另外600,000条记录完全不切实际。
表索引显示在附加图像中:
如果我基于contact.id = 123456进行搜索,则查询时间将降至约0.004秒。 contact.id是表中的主键。 external_identifier是一个唯一索引。
答案 0 :(得分:1)
我知道这是一个老线程,但因为它与CiviCRM有关,我以为我会推出我的想法。修复实际上不是最佳实践,因为您已更改其中一个核心打包表以使查询运行得更快。虽然这可能对你没问题,但我绝对不会向所有人推荐这个。
您的解决方案可能突出显示了查询的问题,但似乎您告诉查询您期望的数字,但实际上数据存储为VARCHAR。所以我认为简单地用单引号括起来就可以了吗?
SELECT *
来自civicrm_contact
联系人
在哪里contact.external_identifier ='123456'
如果没有这个,我很确定(已与Oracle合作多年)会发生隐式数据类型转换,因此查询无法使用INDEX。
解释计划应证明这一理论。
由于
帕尔韦兹
答案 1 :(得分:0)
您似乎使用BTREE
索引。如果您未对此列执行任何范围查询(使用<
,>
,<=
或>=
),则可能需要使用基于哈希的索引。< / p>
有关详细信息,请参阅Comparison of B-Tree and Hash Indexes。
请参阅here确切的语法。
答案 2 :(得分:0)
我将结构更改为使用INT类型的external_identifier而不是VARCHAR。速度增加到0.006s
我不确定这是否会产生更广泛的影响
答案 3 :(得分:0)
我怀疑数据类型转换是个问题。我想知道它是否与索引字段的大小限制有关。作为btree意味着索引键可能比散列键大得多。这有必要吗?将外部ID存储在单独的表中并根据数字ID链接它们会更好吗?
这里的问题多于答案。