【问题标题】:NULL used as index key instead of possible key in MySQL dbNULL 用作索引键而不是 MySQL 数据库中的可能键
【发布时间】:2013-10-15 20:32:51
【问题描述】:

我正在运行以下查询:

SELECT p.val1, p.val2, p.val3, p.val4, p.val5, p.val6, p.val7, p.val8
FROM db1.tbl1 AS p
INNER JOIN db2.tbl2 vp ON p.pid = vp.pid
INNER JOIN db2.tbl1 AS vs ON vp.vid = vs.vid
INNER JOIN db3.tbl1 AS sa ON vs.sid = sa.sid
LEFT JOIN db4.tbl1 AS fs ON p.aid = fs.aid
WHERE sa.id =  '11594'
AND fs.aid IS NULL 
ORDER BY IF( (
ISNULL( egl ) 
OR egl =  '' ) , 1, 0
), egl DESC 
LIMIT 15 
OFFSET 0

不幸的是,它只是在运行时挂起。 运行EXPLAIN 会为我提供以下信息:

|  id | select_type | table | type  | possible_keys                     | key        | key_len | ref        |  rows  | Extra 
|*---*|*-----------*|*-----*|*-----*|*---------------------------------*|*----------*|*-------*|*----------*|*------*|*--------------
|  1  | SIMPLE      |   sa  | const | PRIMARY,s_key,p_key,n_key,ignored |   PRIMARY  |    4    | const      |   1    | Using filesort
|  1  | SIMPLE      |   p   |  ALL  | PRIMARY, pid                      |    NULL    |  NULL   | NULL       | 744704 |   
|  1  | SIMPLE      |   vp  |  ref  | PRIMARY,pid                       |   pid      |   130   | db1.p.pid  |   1    | Using index
|  1  | SIMPLE      |   vs  |  ref  | vid                               |   vid      |   130   | db2.vp.vid |   1    | Using where
|  1  | SIMPLE      |   fs  |  ref  | a_key                             |   a_key    |   97    | func       |   1    | Using where; Using index

如果我和USE INDEXFORCE INDEXFROM db1.tbl1 AS p 之后,它不会改变任何事情。

我的假设是表p 没有使用任何索引。这个假设正确吗? 此查询不使用其中一个可能的键的一些原因是什么?

【问题讨论】:

  • 通过运行“分析表 X”确保正确的索引基数。具有 NULL 基数的索引总是被忽略。

标签: mysql indexing explain


【解决方案1】:

问题出在ORDER BY 子句上。 dbms 试图在加入之前将其应用于db1.tbl1(显然)。将查询包装在一个选择中并将ORDER BY 放在外面使dbms 按预期工作。

SELECT * FROM 
(SELECT p.val1, p.val2, p.val3, p.val4, p.val5, p.val6, p.val7, p.val8
FROM db1.tbl1 AS p
INNER JOIN db2.tbl2 vp ON p.pid = vp.pid
INNER JOIN db2.tbl1 AS vs ON vp.vid = vs.vid
INNER JOIN db3.tbl1 AS sa ON vs.sid = sa.sid
LEFT JOIN db4.tbl1 AS fs ON p.aid = fs.aid
WHERE sa.id =  '11594'
AND fs.aid IS NULL) AS tmp
ORDER BY IF( (
ISNULL( egl ) 
OR egl =  '' ) , 1, 0
), egl DESC 
LIMIT 15 
OFFSET 0

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-10
    • 2019-01-04
    • 1970-01-01
    • 1970-01-01
    • 2017-04-30
    • 2012-04-29
    相关资源
    最近更新 更多