精华内容
下载资源
问答
  • Laravel的Validation还是蛮好用的,使用Validator可以非常方便的验证表单,它提供了unique唯一性验证,但是默认只能验证一个字段,那遇到两个甚至字段的联合索引,需要满足复杂条件唯一性怎么实现呢 Validator...
  •   给字段一个索引叫组合索引。 问题:在哪些场景中,组合索引会失效? 场景: 数据表:job_status_trace_log【说明:id是主键】 数据量:35w 创建索引:ALTER table job_status_trace_log add INDEX creation_...
    什么是组合索引?

      由多个字段组成的索引叫组合索引。

    问题:在哪些场景中,组合索引会失效?

    场景

    数据表:job_status_trace_log【说明:id是主键】
    数据量:35w
    创建索引:ALTER table job_status_trace_log add INDEX creation_time_index(creation_time,job_name,source)
    

    注意:创建表的时候,字段要超过组合索引字段的个数,因为它会命中覆盖索引,导致跟我下面测试的数据不一致

    例子:组合索引(a,b,c)都有哪些排列组合

    • a,b,c
    • a,c,b
    • c,a,b
    • c,b,a
    • b,c,a
    • a,b
    • b,a
    • a,c
    • c,a
    • b,c
    • a
    • b
    • c
    • …就列举那么多已经够了

    先看看总结,再看验证过程,可能会更棒

    总结:

    1、组合索引字段无论顺序如何改变都会用到索引,前提是所有字段都在where条件上
    2、如果想要使用一个或者两个字段在where条件上,必须有组合索引里的第一个字段,但是与顺序无关,例如a,c或c,a,这种场景是可以命中索引的。但是,b,c或c,b这种是不会命中索引的。
    3、如果组合索引存在范围查询,则组合索引可能会命中索引,这个跟B+Tree的叶子节点中存储的数据是否在当前的叶子节点中,即InnoDB存储引擎的最小存储单元——页,InnoDB页的大小默认是16k,可以通过参数查看页的默认大小:show global status like ‘innodb_page_size’;如果想要修改InnoDB页的大小,需要通过修改mysql源码才可以修改,找到源码文件(storage/innobase/include/univ.i),找到参数:UNIV_PAGE_SIZE,该参数必须是2的n次方,例如4k、8k、16k、32k、64k等等。
    4、order by 只能使用a,才能用到索引

    排列组合一:a,b,c,恭喜成功命中索引
    mysql> explain select * from job_status_trace_log where creation_time = '2020-01-01 00:00:00' and job_name ='member.channelRouteTask' and source='LITE_EXECUTOR'\G
    *************************** 1.***************************
    id           : 1
    select_type  : SIMPLE
    table        : job_status_trace_log
    partitions   : NULL
    type         : ref
    possible_keys: creation_time_index
    key          : creation_time_index
    key_len      : 609
    ref          : const,const,const
    rows         : 1
    filtered     : 100.00
    Extra        : NULL
    1 行于数据集 (0.02)
    
    排列组合二:a,c,b,恭喜成功命中索引
    mysql> explain select * from job_status_trace_log where creation_time = '2020-01-01 00:00:00' and source='LITE_EXECUTOR' and job_name ='member.channelRouteTask'\G
    *************************** 1.***************************
    id           : 1
    select_type  : SIMPLE
    table        : job_status_trace_log
    partitions   : NULL
    type         : ref
    possible_keys: creation_time_index
    key          : creation_time_index
    key_len      : 609
    ref          : const,const,const
    rows         : 1
    filtered     : 100.00
    Extra        : NULL
    1 行于数据集 (0.03)
    
    排列组合三:c,a,b,恭喜成功命中索引
    mysql> explain select * from job_status_trace_log where source='LITE_EXECUTOR' and creation_time = '2020-01-01 00:00:00' and job_name ='member.channelRouteTask'\G
    *************************** 1.***************************
    id           : 1
    select_type  : SIMPLE
    table        : job_status_trace_log
    partitions   : NULL
    type         : ref
    possible_keys: creation_time_index
    key          : creation_time_index
    key_len      : 609
    ref          : const,const,const
    rows         : 1
    filtered     : 100.00
    Extra        : NULL
    1 行于数据集 (0.03)
    
    排列组合四:c,b,a,恭喜成功命中索引
    mysql> explain select * from job_status_trace_log where source='LITE_EXECUTOR' and job_name ='member.channelRouteTask' and creation_time = '2020-01-01 00:00:00'\G
    *************************** 1.***************************
    id           : 1
    select_type  : SIMPLE
    table        : job_status_trace_log
    partitions   : NULL
    type         : ref
    possible_keys: creation_time_index
    key          : creation_time_index
    key_len      : 609
    ref          : const,const,const
    rows         : 1
    filtered     : 100.00
    Extra        : NULL
    1 行于数据集 (0.07)
    
    排列组合五:b,c,a,恭喜成功命中索引
    mysql> explain select * from job_status_trace_log where job_name ='member.channelRouteTask' and source='LITE_EXECUTOR' and creation_time = '2020-01-01 00:00:00'\G
    *************************** 1.***************************
    id           : 1
    select_type  : SIMPLE
    table        : job_status_trace_log
    partitions   : NULL
    type         : ref
    possible_keys: creation_time_index
    key          : creation_time_index
    key_len      : 609
    ref          : const,const,const
    rows         : 1
    filtered     : 100.00
    Extra        : NULL
    1 行于数据集 (0.02)
    
    排列组合六:a,b,恭喜成功命中索引
    mysql> explain select * from job_status_trace_log where creation_time = '2020-01-01 00:00:00' and job_name ='member.channelRouteTask'\G
    *************************** 1.***************************
    id           : 1
    select_type  : SIMPLE
    table        : job_status_trace_log
    partitions   : NULL
    type         : ref
    possible_keys: creation_time_index
    key          : creation_time_index
    key_len      : 407
    ref          : const,const
    rows         : 2
    filtered     : 100.00
    Extra        : NULL
    1 行于数据集 (0.04)
    
    排列组合七:b,a,恭喜成功命中索引
    mysql> explain select * from job_status_trace_log where job_name ='member.channelRouteTask' and creation_time = '2020-01-01 00:00:00'\G
    *************************** 1.***************************
    id           : 1
    select_type  : SIMPLE
    table        : job_status_trace_log
    partitions   : NULL
    type         : ref
    possible_keys: creation_time_index
    key          : creation_time_index
    key_len      : 407
    ref          : const,const
    rows         : 2
    filtered     : 100.00
    Extra        : NULL
    1 行于数据集 (0.03)
    
    排列组合八:a,c,恭喜成功命中索引
    mysql> explain select * from job_status_trace_log where creation_time = '2020-01-01 00:00:00' and source='11'\G 
    *************************** 1.***************************
    id           : 1
    select_type  : SIMPLE
    table        : job_status_trace_log
    partitions   : NULL
    type         : ref
    possible_keys: creation_time_index
    key          : creation_time_index
    key_len      : 5
    ref          : const
    rows         : 17
    filtered     : 10.00
    Extra        : Using index condition
    1 行于数据集 (0.04)
    
    排列组合九:c,a,恭喜成功命中索引
    mysql> explain select * from job_status_trace_log where source='11' and creation_time = '2020-01-01 00:00:00'\G
    *************************** 1.***************************
    id           : 1
    select_type  : SIMPLE
    table        : job_status_trace_log
    partitions   : NULL
    type         : ref
    possible_keys: creation_time_index
    key          : creation_time_index
    key_len      : 5
    ref          : const
    rows         : 17
    filtered     : 10.00
    Extra        : Using index condition
    1 行于数据集 (0.04)
    
    排列组合十:b,c,很遗憾全表扫描了
    mysql> explain select * from job_status_trace_log where job_name ='member.channelRouteTask' and source='LITE_EXECUTOR'\G
    *************************** 1.***************************
    id           : 1
    select_type  : SIMPLE
    table        : job_status_trace_log
    partitions   : NULL
    type         : ALL
    possible_keys: NULL
    key          : NULL
    key_len      : NULL
    ref          : NULL
    rows         : 4316676
    filtered     : 1.00
    Extra        : Using where
    1 行于数据集 (0.03)
    
    排列组合十一:a,恭喜成功命中索引
    mysql> explain select * from job_status_trace_log where creation_time = '2020-01-01 00:00:00'\G
    *************************** 1.***************************
    id           : 1
    select_type  : SIMPLE
    table        : job_status_trace_log
    partitions   : NULL
    type         : ref
    possible_keys: creation_time_index
    key          : creation_time_index
    key_len      : 5
    ref          : const
    rows         : 17
    filtered     : 100.00
    Extra        : NULL
    1 行于数据集 (0.02)
    
    排列组合十二:b,很遗憾全表扫描了
    mysql> explain select * from job_status_trace_log where job_name ='member.channelRouteTask'\G
    *************************** 1.***************************
    id           : 1
    select_type  : SIMPLE
    table        : job_status_trace_log
    partitions   : NULL
    type         : ALL
    possible_keys: NULL
    key          : NULL
    key_len      : NULL
    ref          : NULL
    rows         : 4316693
    filtered     : 10.00
    Extra        : Using where
    1 行于数据集 (0.04)
    
    排列组合十三:c,很遗憾全表扫描了
    mysql> explain select * from job_status_trace_log where source='LITE_EXECUTOR'\G 
    *************************** 1.***************************
    id           : 1
    select_type  : SIMPLE
    table        : job_status_trace_log
    partitions   : NULL
    type         : ALL
    possible_keys: NULL
    key          : NULL
    key_len      : NULL
    ref          : NULL
    rows         : 4316702
    filtered     : 10.00
    Extra        : Using where
    1 行于数据集 (0.06)
    
    排列组合十四:a>0,b=1,c=1,很遗憾全表扫描了
    mysql> explain select * from job_status_trace_log where creation_time > '2020-01-01 00:00:00' and job_name ='member.channelRouteTask' and source='LITE_EXECUTOR'\G
    *************************** 1.***************************
    id           : 1
    select_type  : SIMPLE
    table        : job_status_trace_log
    partitions   : NULL
    type         : ALL
    possible_keys: creation_time_index
    key          : NULL
    key_len      : NULL
    ref          : NULL
    rows         : 4316703
    filtered     : 0.38
    Extra        : Using where
    1 行于数据集 (0.04)
    
    
    排列组合十五:a=1,b>0,c=1,很遗憾全表扫描了
    mysql> explain select * from job_status_trace_log where  job_name ='member.channelRouteTask' and creation_time > '2020-01-01 00:00:00' and source='LITE_EXECUTOR'\G
    *************************** 1.***************************
    id           : 1
    select_type  : SIMPLE
    table        : job_status_trace_log
    partitions   : NULL
    type         : ALL
    possible_keys: creation_time_index
    key          : NULL
    key_len      : NULL
    ref          : NULL
    rows         : 4316727
    filtered     : 0.38
    Extra        : Using where
    1 行于数据集 (0.02)
    
    排列组合十六:a=1,b=1,c>0,很遗憾全表扫描了
    mysql> explain select * from job_status_trace_log where  job_name ='member.channelRouteTask'  and source='LITE_EXECUTOR' and creation_time > '2020-01-01 00:00:00'\G
    *************************** 1.***************************
    id           : 1
    select_type  : SIMPLE
    table        : job_status_trace_log
    partitions   : NULL
    type         : ALL
    possible_keys: creation_time_index
    key          : NULL
    key_len      : NULL
    ref          : NULL
    rows         : 4316730
    filtered     : 0.38
    Extra        : Using where
    1 行于数据集 (0.06)
    
    排列组合十七:a>0,很遗憾全表扫描了
    mysql> explain select * from job_status_trace_log where creation_time > '2020-01-01 00:00:00'\G
    *************************** 1.***************************
    id           : 1
    select_type  : SIMPLE
    table        : job_status_trace_log
    partitions   : NULL
    type         : ALL
    possible_keys: creation_time_index
    key          : NULL
    key_len      : NULL
    ref          : NULL
    rows         : 4316730
    filtered     : 38.09
    Extra        : Using where
    1 行于数据集 (0.03)
    
    总结:
    • 1、组合索引字段无论顺序如何改变都会用到索引,前提是所有字段都在where条件上。
    • 2、如果想要使用一个或者两个字段在where条件上,必须有组合索引里的第一个字段,但是与顺序无关,例如a,c或c,a,这种场景是可以命中索引的。但是,b,c或c,b这种是不会命中索引的。
    • 3、如果组合索引存在范围查询,则组合索引可能会命中索引,这个跟B+Tree的叶子节点中存储的数据是否在当前的叶子节点中,即InnoDB存储引擎的最小存储单元——页,InnoDB页的大小默认是16k,可以通过参数查看页的默认大小:show global status like ‘innodb_page_size’;如果想要修改InnoDB页的大小,需要通过修改mysql源码才可以修改,找到源码文件(storage/innobase/include/univ.i),找到参数:UNIV_PAGE_SIZE,该参数必须是2的n次方,例如4k、8k、16k、32k、64k等等。
    • 4、order by 只能使用a,才能用到索引。

    欢迎关注我的微信公众号,里面有很多干货,各种面试题
    在这里插入图片描述

    展开全文
  • MySQL--组合索引个单列索引

    万次阅读 2018-08-27 18:03:23
    有一张职工表emp,表设计如下: 创建了两个单列索引:idx_ename、idx_deptno 执行select * from emp where ename='RgfgEv' and deptno='102' 用explain进行分析只用到了idx_ename...创建一个组合索引:idx_n...

    有一张职工表emp,表设计如下:
    这里写图片描述

    创建了两个单列索引:idx_ename、idx_deptno
    这里写图片描述

    执行select * from emp where ename='RgfgEv' and deptno='102'

    用explain进行分析只用到了idx_ename一个索引。

    这里写图片描述

    (当有多个单列索引时,mysql只能用到其中那个它认为最有效率的单列索引)

    创建一个组合索引:idx_name_deptno

    这里写图片描述

    分别执行如下sql:

    select * from emp where ename='JFWTBd' and deptno='107';

    这里写图片描述

    索引起作用

    select * from emp where deptno='107' and ename='JFWTBd'

    这里写图片描述
    索引起作用

    select * from emp where ename='JFWTBd'

    这里写图片描述

    索引起作用

    select * from emp where deptno='107'

    这里写图片描述
    索引失效

    这就是mysql遵循的最左前缀原则。

    展开全文
  • 一个表中有三个字段,XX,YY,ZZ,如果要建立给这三个字段组合索引(Composite Index),组合索引字段的顺序应该遵循怎样一个原则。一般的原则:越离散的字段越靠前。哪个列可以降低索引的扫描成本就放在前面。比如...

    一个表中有三个字段,XX,YY,ZZ,如果要建立给这三个字段建组合索引(Composite Index),组合索引中字段的顺序应该遵循怎样一个原则。

    一般的原则:越离散的字段越靠前。哪个列可以降低索引的扫描成本就放在前面。

    比如:下位三个字段的离散情况
    XX:2
    YY:1000
    ZZ:50000

    那么建立索引的顺序应该为:ZZ,YY,XX

    CREATE INDEX t_idx ON t (zz,yy,xx);


    但是如果where条件中,三个字段的条件都是通过"="号连接的,那么组合索引中字段的顺序就是无所谓了。

    Refer:https://forums.oracle.com/forums/thread.jspa?threadID=2425684

    Because you are using equality conditions in your predicate, then the order should be XX, YY, ZZ for maximum compression. Others are suggesting ZZ should be first because it is more selective (probably). But if you are using equals (=) for all 3, then that really does not matter.


    或者It’s Less Efficient To Have Low Cardinality Leading Columns In An Index (Right) ?  (轻功需好)

    In actual fact, there’s no real difference in navigating to the specific leaf block of interest for an index on (ID, CODE) compared to an index based on (CODE, ID), providing both indexed columns are known.


    再或者 http://www.oraclemagician.com/white_papers/index_order.pdf

    Consider the following indexes:
    INDEX1: (ZIP_CODE, GENDER)
    INDEX2: (GENDER, ZIP_CODE)
    Assume we are looking for the combination of Zip_Code = 94568 and Gender = ‘Male.’ Before Oracle traverses the index, it combines the two conditions. The composite value, something like 94568_Male has the same discriminatory value as Male_94568.

    展开全文
  • 转载自随心2017的博客 ...你创建一个 组合索引 ( 班级, 姓名) 那么 SELECT * FROM 学生表 WHERE 班级='2010级3班' AND 姓名='张三' 将使用索引. SELECT * FROM 学生表 WHERE 班级='2010级3班' 将使用索引...

    转载自随心2017的博客

    聚合索引

    例如你有一个 学生表。

    字段包含 学号, 班级, 姓名,性别, 出生年月日。

    你创建一个 组合索引 ( 班级, 姓名)

    那么

    SELECT * FROM  学生表  WHERE  班级='2010级3班'  AND  姓名='张三' 
    

    将使用索引.

    SELECT * FROM  学生表  WHERE  班级='2010级3班'      
    

    将使用索引 .

    SELECT * FROM  学生表  WHERE  姓名='张三'     
    

    将不使用索引。

    单独索引

    删除掉上面的索引

    再创建两个 独立索引

    索引1 ( 班级)

    索引2 ( 姓名)

    那么

    SELECT * FROM  学生表  WHERE  班级='2010级3班'  AND  姓名='张三'  
    

    将根据数据库的分析信息, 自动选择使用索引1或者索引2中的一个 (理论上会使用 索引2, 因为 姓名=张三的人少, 优先找到所有 姓名为 张三的人以后, 然后再从这些数据中, 找班级 = ‘2010级3班’ 的

    SELECT * FROM  学生表  WHERE  班级='2010级3班'      
    

    将使用索引1 .

    SELECT * FROM  学生表  WHERE  姓名='张三'     
    

    将使用索引2。

    总结

    组合索引是组合条件查询时有条件查询的顺序很重要,

    展开全文
  • 组合索引中列的顺序问题

    千次阅读 2020-10-28 17:37:59
    兹有 Index (A,B,C) ——组合索引多字段是有序的,并且是个完整的BTree 索引。 下面条件可以用该组合索引查询: A>5 A=5 AND B>6 A=5 AND B=6 AND C=7 A=5 AND B IN (2,3) AND C>5 下面条件将不能...
  • 咨询方法-一种基于个相关字段组合索引存储结构及建立、查询与维护方法.zip
  • mysql组合索引字段顺序

    千次阅读 2019-06-11 17:15:25
    一般来说,可能是某些字段没有创建索引,或者是组合索引字段的顺序与查询语句中字段的顺序不符。 看下面的例子: 假设有一张订单表(orders),包含order_id和product_id二个字段。 一共有31条数据。符合下面语句的...
  • sql 表中同一个字段已经创建了单字段索引还能在字段创建组合索引吗?
  • 索引B-Tree: 一般来说, MySQL 中的 B-Tree 索引的物理文件大多都是以 B+tree的结构来存储的,也就是所有实际需要的数据都存放于 Tree 的 Leaf Node,而且到任何一个 Leaf Node 的最短路径的长度都是完全相同的,...
  • oracle复合索引介绍(多字段索引)

    千次阅读 2019-10-31 16:31:44
    如果分别按纳税人识别号,税务机关代码,月份3个字段查询,每个字段在该表中的可选性或约束性都不强,如一个纳税人识别号有很纳税记录,一个税务机关代码和同一月份记录就更了,所以3个字段合起来,"某个纳税人识别号+...
  • SQL优化之组合索引字段的顺序

    千次阅读 2019-04-03 15:41:01
    SQL优化之组合索引字段的顺序 记一次SQL优化:组合索引字段顺序有讲究,越离散的字段越靠前,哪个列可以降低索引扫描成本放在前面。 Refer:https://blog.csdn.net/pan_tian/article/details/8279501 或者 ...
  • mysql多字段唯一索引

    千次阅读 2018-07-27 16:58:00
    项目中需要用到联合...例如:user表中有userID,userName两个字段,如果不希望有2条一模一样的记录,需要给user表添加字段的联合唯一索引: alter table user add nuique index(user_id,user_name); 例如: alte...
  • 主要讨论MySQL选择索引时单列单列索引索引使用,以及索引的最左前缀原则,需要的朋友可以参考下
  • 建立组合索引字段顺序优化

    千次阅读 2019-01-14 21:39:25
    建立组合索引字段顺序优化 简介 组合索引我们经常用到,建立组合索引大家也都会,但是如何考虑建立组合索引的顺序是一个值得推敲的事情。 正文 1. 尽量把最常用的字段放在最前面 对于我们需要创建的组合索引,如果...
  • 1、联合索引是由字段组成的索引。2、查询时使用联合索引的一个字段,如果这个字段在联合索引中所有字段的第一个,那就会用到索引,否则就无法使用到索引。3、联合索引IDX(字段A,字段B,字段C,字段D),当仅使用...
  • 背景: 为了提高数据库效率,建索引是家常便饭;那么...
  • MySQL通常使用GROUPBY(本质上是排序动作)完成DISTINCT操作,如果DISTINCT操作和ORDERBY操作组合使用,通常会用到临时表.这样会影响性能. 在一些情况下,MySQL可以使用索引优化DISTINCT操作,但需要活学活用.本文涉及一个...
  • 例如你有一个 学生表。...你创建一个 组合索引 ( 班级, 姓名) 那么 SELECT * FROM 学生表 WHERE 班级='2010级3班' AND 姓名='张三' 将使用索引. SELECT * FROM 学生表 WHERE 班级='2010级3班'
  • oracle中字段组成唯一索引约束

    千次阅读 2018-11-26 18:59:02
    已经验证!!!欢迎相互学习交流 --原来EXPENSE_ITEM_CODE, EXPENSE_TYPE_CODE, EXP_REPORT_TYPE_CODE这三个为唯一索引...注意事项(报错dupplicate keys found,若表中要创建的唯一索引约束的四个字段在数据库该表...
  • MongoDB组合索引

    千次阅读 2018-08-17 11:00:15
    MongoDB支持组合索引,就是一个索引结构里面包括一个集合文档的字段。下图展示了一个拥有两个字段组合索引组合索引字段不能超过31个 组合索引查询的时候支持字段的匹配   一、创建一个组合...
  • 2 多字段唯一键 多字段唯一键怎么处理?两种方法: 1 手动修改表 CREATE UNIQUE INDEX name ON table (column [, ...]); 2 代码中配置(注意必须自动建表,且如果已建好的表要先删除) // 多字段唯一键 fu....
  • PostgreSQL 多字段任意组合搜索

    千次阅读 2019-09-06 16:55:24
    这个时候就会遇到任意列组合查询的情况了,因为你不知道用户会按照哪些条件进行筛选,可能你会说那我在所有列都建立索引不就行了?的确这是一种方法,但是如果某张表有几百上千个列时候呢,PostgreSQL为我们 提供了几种...
  • Elasticsearch 可以用于:分布式实时文件存储,并将每一个字段都编入索引,使其可以被搜索;实时分析的分布式搜索引擎;可以扩展到上百台服务器,处理PB级别的结构化或非结构化数据。 Elasticsearch的文件存储   ...
  • MySQL单列索引和组合索引的区别

    千次阅读 2017-02-05 20:44:48
    MySQL单列索引和组合索引究竟有何区别呢?下文形象地对比了MySQL单列索引和组合索引的区别,希望...MySQL单列索引和组合索引的区别可能有很多人还不是十分的了解,下面就为您分析两者的主要区别,供您参考学
  • 有时候我们业务情景需要多字段组合唯一性,这里举例 Navicat 设置,如图所示。 Ps:但我们一般企业级开发,不推荐用物理约束死,推荐用逻辑来判断。 ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 137,886
精华内容 55,154
关键字:

多字段组合索引