【问题标题】:using ifnull with index creation in mysql在mysql中使用ifnull和索引创建
【发布时间】:2018-10-30 02:06:05
【问题描述】:

我正在尝试在 MySQL 中创建索引,而查询将首先检查哪些列不为空。检查后,它将在不为空的列上创建索引。但是,我没有成功创建它,它说我有一个错误,有人可以帮助我吗?请在下面查看我的代码

create index IDX_KSE_NO_01 on tb_kse(ifnull(ss_no, id_no);

【问题讨论】:

  • 目标是什么? ORDER BY ISNULL(...)?还是SELECT ISNULL...?还是缩小索引?或者不显示带有NULL 的那些?

标签: mysql sql indexing ifnull


【解决方案1】:

@lad2025 说的对,MySQL 不支持基于函数的索引(like PostgreSQL does),但是 MySQL 5.7 引入了基于表达式的virtual generated columns 的功能,然后您可以在虚拟列上创建索引。

ALTER TABLE tb_kse ADD COLUMN either_no VARCHAR(10) AS (IFNULL(ss_no, id_no));
CREATE INDEX IDX_KSE_NO_01 ON tb_kse(either_no);

【讨论】:

    【解决方案2】:

    MySQL 不支持基于函数的索引。您应该创建普通索引:

    create index IDX_KSE_NO_01 on tb_kse(ss_no);
    create index IDX_KSE_NO_02 on tb_kse(id_no);
    

    并重写您的查询(OR-Expansion):

    SELECT *
    FROM tb_kse WHERE ss_no = ?
    UNION 
    SELECT *
    FROM tb_kse
    WHERE ss_no IS NULL AND id_no = ?;
    

    DBFiddle Demo


    另一种方法是创建生成的列并在其上创建索引:

    CREATE TABLE tb_kse(id_no INT, ss_no INT,
           gen_col INT GENERATED ALWAYS AS (ifnull(ss_no, id_no)) STORED);
    
    create index IDX_KSE_NO_01 on tb_kse(gen_col);
    
    SELECT *
    FROM tb_kse
    WHERE gen_col = ?;
    

    DBFiddle Demo 2

    【讨论】:

    • 这两个索引应该替换为一个复合索引:(ss_no, id_no)——这样对于第一个 SELECT 有效,而对于第二个则更有效。
    猜你喜欢
    • 1970-01-01
    • 2012-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多