SQL - SELECT 的奇怪问题

SQL - Strange issue with SELECT

我有一个奇怪的情况,一个简单的 select 按列 pqth_scan_code 来自以下 table:

tablepqth_

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 

根据来自 table pqth_ 的数据,我创建了以下 table,其中 pqthc_id = pqth_idpqthc_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    

相同的查询 query1,在 table pqthc 上用了 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")

我的问题是 为什么 pqth_scan_code 的 SELECT 很慢而 pqth_id 的 SELECT 最快? 两列已编入索引。

为了测试,请从这里获取导出 link

MySQL 和 MariaDB 服务器

的行为相同

您必须了解主键和索引的概念以及它们如何帮助搜索, 参考文档 here

首先 pqthc_scan_code 没有 index/key 而 pqthc_id 有,键有助于加快搜索速度。

另一个区别是 pqthc_id 是一个整数,而 pqthc_scan_code 是一个字符串。比较整数比比较字符串更有效。

您应该避免在非常大的表中搜索字符串。

您可以在 pqthc_scan_code 中添加一个 index/key,但我不知道它会有多大帮助。

您可以在查询前面使用 EXPLAIN 来尝试找出需要这么长时间的原因 More info on EXPLAIN

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) table 更小,或者 (2) 你之前 运行 查询,从而缓存 RAM 中需要的内容。

请不要在列名称前加上 table 名称。
请不要让 table 个名字彼此靠得太近以至于难以区分。 (pqthpqthc)

SELECT  *
    FROM  `pqth`
    WHERE  pqth_id = 
      ( SELECT  pqthc_id
            From  pqthc
            where  pqthc_scan_code = "7900722!30@3#6$EN"
      )

构造 IN ( SELECT ... ) 效率不高。

难得有两个table同一个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" 

如果是'correct',那我推荐这个'covering'索引:

INDEX(scan_code, id)

而不是我之前推荐的较短的 INDEX(scan_code)

More on indexing.