【发布时间】:2013-02-13 06:36:19
【问题描述】:
我有 3 个表(不写所有和实际的字段名称)
-
合同(约 30 000 行)
|id|client_id|contract_nr|....
-
容器(~30 000 行
|id|contract_nr|phone_1(varchar)|....
-
客户端(~35 000 行)
|id|phone_2(varchar)|phone_3(varchar)|phone_4(varchar)|....
我需要搜索电话号码,所以我试试这个 - 如果我搜索一个电话号码,例如在 container.phone_1 中
SELECT *
FROM contract JOIN client
ON contract.client_id = client.id
JOIN container
ON contract.contract_nr = container.contract_nr
WHERE container.phone_1 LIKE '264%'
id select_type table type possible_keys key key_len ref rows filtered Extra
-------------------------------------------------------------------------------------------------------------
1 SIMPLE container range contract_nr,phone_1 phone_1 63 NULL 912 100.00 Using where
1 SIMPLE contract ref contract_nr,client_id contract_nr 26 container.contract_nr 1 100.00
1 SIMPLE client eq_ref PRIMARY,id PRIMARY 3 contract.client_id 1 100.00
但是当我开始使用 OR 从客户端添加电话号码时
SELECT *
FROM contract JOIN client
ON contract.client_id = client.id
JOIN container ON contract.contract_nr = container.contract_nr
WHERE (
container.phone_1 LIKE '264%' OR
client.phone_2 LIKE '264%' OR
client_phone_3 LIKE '264%'
)
解释扩展:
id select_type table type possible_keys key key_len ref rows filtered Extra
-------------------------------------------------------------------------------------------------------------
1 SIMPLE container ALL k_ligums,k_telef NULL NULL NULL 32113 100.00
1 SIMPLE contract ref contract_nr,client_id contract_nr 26 za.zaao_konteineri.k_ligums 1 100.00
1 SIMPLE client eq_ref PRIMARY,id PRIMARY 3 contract.client_id 1 100.00 Using where
我已经索引了所有用于连接表和用于搜索的字段。 我还尝试为包含所有搜索行的客户端和容器表创建多列索引 - 没有区别。
如何避免扫描容器表的 32113 行?
【问题讨论】:
-
连接会影响大型数据集中的查询性能。如果可能,请考虑避免使用它们,或者如果您需要大规模处理数据,请考虑重组数据
-
当我在查询中添加“OR”时,问题就开始了——直到那时,连接都没有问题!将连接替换为 table1.field = table2.field - 没有区别 - 仍然执行全扫描!
-
数据集大小不重要恕我直言。如果您执行
EXPLAIN SELECT * ...,您将获得一个执行计划。请发布结果,因为这对解决查询性能问题有很大帮助。 -
“解释扩展”在我的帖子中!
-
对不起,伙计 - 你是 - 似乎将 2 个表中的
like条件混合在一起会阻止在 container.phone_1 上使用索引。黑暗中的真实镜头-您是否尝试过更改括号括起来的条件?他们目前都在一起 - 尝试将客户的括号放在一起WHERE container.phone_1 LIKE '264%' OR (client.phone_2 LIKE '264%' OR client_phone_3 LIKE '264%')
标签: mysql full-table-scan