SQL - SELECT的奇怪问题

时间:2016-04-15 07:54:34

标签: mysql sql mariadb

我遇到一个奇怪的情况,只需按下表中的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_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    

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服务器相同的行为

3 个答案:

答案 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中所需的内容。

请不要使用表名为列名添加前缀 请不要让表名彼此如此接近以至于难以区分。 (pqthpqthc

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)

More on indexing

答案 1 :(得分:0)

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

答案 2 :(得分:0)

首先,pqthc_scan_code没有索引/键,pqthc_id没有,密钥有助于加快搜索速度。

另一个区别是pqthc_id是一个整数,其中pqthc_scan_code是一个字符串。比较整数比比较字符串要有效得多。

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

您可以为pqthc_scan_code添加索引/密钥,但我不知道它会有多大帮助。

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