我遇到一个奇怪的情况,只需按下表中的pqth_scan_code
列进行简单选择:
table pqth _
Field Type Null Key Default Extra
pqth_id int(11) NO PRI NULL auto_increment
pqth_scan_code varchar(250) NO NULL
pqth_info text YES NULL
pqth_opk int(11) NO 999
查询1
此查询执行时间为12.7221秒
SELECT * FROM `pqth_` WHERE pqth_scan_code = "7900722!30@3#6$EN"
查询2 此查询花了0.0003秒执行
SELECT * FROM `pqth` WHERE `pqth_id`=27597
根据表pqth_
中的数据,我创建了下表,其中pqthc_id
= pqth_id
和pqthc_scan_code
= pqth_scan_code
table pqthc
Field Type Null Key Default Extra
pqthc_id int(11) NO PRI NULL
pqthc_scan_code tinytext NO NULL
表pqthc
上的同一查询 query1 耗时0.0259秒
SELECT * FROM `pqthc` WHERE pqthc_scan_code = "7900722!30@3#6$EN"
如果我运行以下查询将花费0.0971秒,非常奇怪。
查询3
SELECT * FROM `pqth` WHERE pqth_id = (SELECT pqthc_id From pqthc where pqthc_scan_code = "7900722!30@3#6$EN")
我的问题是为什么SELECT pqth_scan_code
的速度很慢而pqth_id
的SELECT最快?这两列都被编入索引。
如需测试,请从此link
获取导出与MySQL和MariaDB服务器相同的行为
答案 0 :(得分:1)
SELECT * FROM `pqth_` WHERE pqth_scan_code = "7900722!30@3#6$EN"
需要INDEX(pqth_scan_code)
。期。讨论结束。
SELECT * FROM `pqth` WHERE `pqth_id`=27597
有一个有用的索引,因为PRIMARY KEY
是一个索引(它是唯一的)。
SELECT * FROM `pqthc` WHERE pqthc_scan_code = "7900722!30@3#6$EN"
还需要INDEX(pqthc_scan_code)
。但它可能更快,因为(1)表更小,或者(2)您之前运行了查询,从而缓存了RAM中所需的内容。
请不要使用表名为列名添加前缀
请不要让表名彼此如此接近以至于难以区分。 (pqth
和pqthc
)
SELECT *
FROM `pqth`
WHERE pqth_id =
( SELECT pqthc_id
From pqthc
where pqthc_scan_code = "7900722!30@3#6$EN"
)
构造IN ( SELECT ... )
效率不高。
很少有两个表具有相同的PRIMARY KEY
;你确定你的意思吗?
改为使用JOIN
:
SELECT a.*
FROM `pqth` AS a
JOIN pqthc AS c ON a.id = c.id
where c.scan_code = "7900722!30@3#6$EN"
如果这是正确的,那么我建议这样做'覆盖'指数:
INDEX(scan_code, id)
而不是我之前推荐的较短INDEX(scan_code)
。
答案 1 :(得分:0)
您必须了解主键和索引的概念以及它们如何帮助搜索, 参考文档here
答案 2 :(得分:0)
首先,pqthc_scan_code
没有索引/键,pqthc_id
没有,密钥有助于加快搜索速度。
另一个区别是pqthc_id
是一个整数,其中pqthc_scan_code
是一个字符串。比较整数比比较字符串要有效得多。
你应该避免在非常大的表中搜索字符串。
您可以为pqthc_scan_code
添加索引/密钥,但我不知道它会有多大帮助。
您可以在查询的前面使用EXPLAIN来尝试找出需要这么长的内容More info on EXPLAIN