精华内容
下载资源
问答
  • 一直以来都没有特别关注单列索引和联合索引的使用区别,今天同事拿个sql来问我优化问题,让我感觉把这方面知识补起来了起因以下是一个不完整的课程,我只把我需要的字段保留下来了,创建了两个单独的索引 idx_city...

    一直以来都没有特别关注单列索引和联合索引的使用区别,今天同事拿个sql来问我优化问题,让我感觉把这方面知识补起来了

    起因

    以下是一个不完整的课程表,我只把我需要的字段保留下来了,创建了两个单独的索引 idx_city_id 和idx_start_course_time

    CREATE TABLE `t_lesson` (

    `id` BIGINT(20) NOT NULL AUTO_INCREMENT,

    `start_course_time` DATETIME NOT NULL COMMENT '预计直播课上课时间',

    `end_course_time` DATETIME NOT NULL COMMENT '预计直播课下课时间',

    `city_id` INT(11) NOT NULL,

    PRIMARY KEY (`id`),

    INDEX `idx_city_id` (`city_id`),

    INDEX `idx_start_course_time` (`start_course_time`),

    );

    执行以下语句:

    explain select * from t_lesson where start_course_time = '2019-08-25 06:00:00' and city_id=4;

    key 代表 MySQL 实际会使用的索引,是idx_start_course_time

    34194ea5a4a3?from=timeline

    explain

    当时脑子出现了以下几个问题:

    MySQL 同时只能使用一个索引吗?

    什么情况下能使用两个索引呢?

    为什么存在两个索引的情况下却只使用了一个索引呢?

    解决问题

    MySQL 同时只能使用一个索引吗?

    网上随处可见,MySQL5.0之后是有索引合并这个概念的,所以第一个问题解决了,MySQL可以同时使用多个索引

    什么情况下能使用两个索引呢?

    以下只做个例子,具体情况可以具体看下索引合并文档

    explain select * from t_lesson where start_course_time = '2019-08-25 06:00:00' or city_id=4;

    34194ea5a4a3?from=timeline

    索引合并.png

    为什么存在两个索引的情况下却只使用了一个索引呢?

    这是我觉得写的比较好的回答:数据库中查询记录时是否每次只能使用一个索引

    引用其中的一句话:"与其说是数据库只支持一条查询语句只使用一个索引,倒不如说N条独立索引同时在一条语句使用的消耗比只使用一个索引还要慢。"

    展开全文
  • 如何让索引只能一个SQL使用

    千次阅读 2014-05-06 14:39:59
    有个徒弟问我,要创建一个索引,去优化一个SQL,但是创建了索引之后其他 SQL 也要用 这个索引,其他SQL慢死了,要优化的SQL又快。遇到这种问题咋搞? 一般遇到这种问题还是很少的。处理的方法很多。我简单的给大家...

    有个徒弟问我,要创建一个索引,去优化一个SQL,但是创建了索引之后其他 SQL 也要用 这个索引,其他SQL慢死了,要优化的SQL又快。遇到这种问题咋搞?

    一般遇到这种问题还是很少的。处理的方法很多。我简单的给大家介绍一种方法。


    还是直接看我实验操作步骤吧。

    在SCOTT账户里面创建一个测试表和一个索引
    SQL> create table test as select * from dba_objects;
    
    表已创建。
    SQL> create index idx_test on test(object_id);
    
    索引已创建。
    SQL> set lines 200 pages 200
    SQL> set autot trace
    SQL> select * from test where object_id=10;
    
    
    执行计划
    ----------------------------------------------------------
    Plan hash value: 2473784974
    
    ----------------------------------------------------------------------------------------
    | Id  | Operation                   | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
    ----------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT            |          |     1 |   207 |     2   (0)| 00:00:01 |
    |   1 |  TABLE ACCESS BY INDEX ROWID| TEST     |     1 |   207 |     2   (0)| 00:00:01 |
    |*  2 |   INDEX RANGE SCAN          | IDX_TEST |     1 |       |     1   (0)| 00:00:01 |
    ----------------------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       2 - access("OBJECT_ID"=10)
    
    Note
    -----
       - dynamic sampling used for this statement (level=6)
    
    
    统计信息
    ----------------------------------------------------------
             44  recursive calls
              0  db block gets
            136  consistent gets
              4  physical reads
              0  redo size
           1404  bytes sent via SQL*Net to client
            420  bytes received via SQL*Net from client
              2  SQL*Net roundtrips to/from client
              0  sorts (memory)
              0  sorts (disk)
              1  rows processed
    然后人工设置索引统计信息 把集群银子搞大(非常大)
    
    SQL> begin
      2    dbms_stats.set_index_stats(ownname  => 'SCOTT',
      3                               indname  => 'IDX_TEST',
      4                               numrows  => 100000000000,
      5                               numlblks => 100000,
      6                               numdist  => 100000,
      7                               avglblk  => 100000,
      8                               avgdblk  => 100000,
      9                               clstfct  => 100000000000);
     10  end;
     11  /
    
    PL/SQL 过程已成功完成。

    SQL> select * from test where object_id=10;
    
    
    执行计划
    ----------------------------------------------------------
    Plan hash value: 1357081020
    
    --------------------------------------------------------------------------
    | Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
    --------------------------------------------------------------------------
    |   0 | SELECT STATEMENT  |      |     1 |   207 |   290   (1)| 00:00:04 |
    |*  1 |  TABLE ACCESS FULL| TEST |     1 |   207 |   290   (1)| 00:00:04 |
    --------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       1 - filter("OBJECT_ID"=10)
    
    Note
    -----
       - dynamic sampling used for this statement (level=6)
    
    
    统计信息
    ----------------------------------------------------------
              0  recursive calls
              0  db block gets
           1039  consistent gets
              0  physical reads
              0  redo size
           1404  bytes sent via SQL*Net to client
            420  bytes received via SQL*Net from client
              2  SQL*Net roundtrips to/from client
              0  sorts (memory)
              0  sorts (disk)
              1  rows processed
    这个时候,所有的SQL都不会走这个索引了,你想让某个SQL走索引,直接hint 让它走就ok了
    SQL> select /*+ index(test idx_test) */ * from test where object_id=10;
    
    
    执行计划
    ----------------------------------------------------------
    Plan hash value: 2473784974
    
    ----------------------------------------------------------------------------------------
    | Id  | Operation                   | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
    ----------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT            |          |     1 |   207 |  1446K  (1)| 04:49:20 |
    |   1 |  TABLE ACCESS BY INDEX ROWID| TEST     |     1 |   207 |  1446K  (1)| 04:49:20 |
    |*  2 |   INDEX RANGE SCAN          | IDX_TEST |     1 |       |    15  (94)| 00:00:01 |
    ----------------------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       2 - access("OBJECT_ID"=10)
    
    Note
    -----
       - dynamic sampling used for this statement (level=6)
    
    
    统计信息
    ----------------------------------------------------------
              0  recursive calls
              0  db block gets
              4  consistent gets
              0  physical reads
              0  redo size
           1404  bytes sent via SQL*Net to client
            420  bytes received via SQL*Net from client
              2  SQL*Net roundtrips to/from client
              0  sorts (memory)
              0  sorts (disk)
              1  rows processed


    
    这样还没完,因为要是有人收集了统计信息,会覆盖我们set的统计信息,所以收集完统计信息之后,要再跑一下那个set的统计信息就ok了。


    展开全文
  • 查询数据库,按主键查询是最快的,每个表只能一个主键列,但是可以有多个普通索引列,主键列要求列的所有内容必须唯一,而普通索引列不要求内容必须唯一。主键就类似我们在学校学习时的学好一样,班级里是唯一的,...

    数据库索引就象书的目录一样,如果在字段上建立了索引,那么以索引列为查询条件时可以加快查询数据的速度。查询数据库,按主键查询是最快的,每个表只能有一个主键列,但是可以有多个普通索引列,主键列要求列的所有内容必须唯一,而普通索引列不要求内容必须唯一。主键就类似我们在学校学习时的学好一样,班级里是唯一的,整个表的每一条记录的主键值在表内都是唯一的,用来唯一标识一条记录

    创建表的时候同时为表创建主键索引和普通索引:例子如下

    mysql> create table student( id int(4) not null auto_increment, name char(20) not null, age tinyint(2) not null default'0', dept varchar(16) default null, primary key(id), key     index_name(name) );

    Query OK, 0 rows affected (0.00 sec)

    注意:

    primary key(id) 

    KEY index_name(name)

    只有int类型且为primary key才可以使用auto_increment

    查看student表的表结构:

    mysql> show create table student\G;

    *************************** 1. row ***************************

    Table: student

    Create Table: CREATE TABLE `student` (

    `id` int(4) NOT NULL AUTO_INCREMENT,

    `name` char(20) NOT NULL,

    `age` tinyint(2) NOT NULL DEFAULT '0',

    `dept` varchar(16) DEFAULT NULL,

    PRIMARY KEY (`id`),

    KEY `index_name` (`name`)

    ) ENGINE=MyISAM DEFAULT CHARSET=utf8

    1 row in set (0.00 sec)

    ERROR:

    No query specified

    删除表的主键:

    alter table student1 drop primary key;

    注意:如果一个表中的primary key设置了AUTO_INCREMENT(自动增加)的话,就删不掉。

    修改student2表的id列为自增主键列:例子

    修改前:

    mysql> desc student2;

    +-------+-------------+------+-----+---------+-------+

    | Field | Type | Null | Key | Default | Extra |

    +-------+-------------+------+-----+---------+-------+

    | id | int(4) | NO | | NULL | |

    | name | char(20) | NO | MUL | NULL | |

    | age | tinyint(2) | NO | | 0 | |

    | dept | varchar(16) | YES | | NULL | |

    +-------+-------------+------+-----+---------+-------+

    4 rows in set (0.00 sec)

    修改后:

    mysql> alter table student2 change id id int primary key auto_increment;

    Query OK, 0 rows affected (0.08 sec)

    Records: 0 Duplicates: 0 Warnings: 0

    mysql> desc student2;

    +-------+-------------+------+-----+---------+----------------+

    | Field | Type | Null | Key | Default | Extra |

    +-------+-------------+------+-----+---------+----------------+

    | id | int(11) | NO | PRI | NULL | auto_increment |

    | name | char(20) | NO | MUL | NULL | |

    | age | tinyint(2) | NO | | 0 | |

    | dept | varchar(16) | YES | | NULL | |

    +-------+-------------+------+-----+---------+----------------+

    4 rows in set (0.00 sec)

    为student2表的删除name列普通索引:例子

    删除前:

    mysql> desc student2;

    +-------+-------------+------+-----+---------+----------------+

    | Field | Type | Null | Key | Default | Extra |

    +-------+-------------+------+-----+---------+----------------+

    | id | int(11) | NO | PRI | NULL | auto_increment |

    | name | char(20) | NO | MUL | NULL | |

    | age | tinyint(2) | NO | | 0 | |

    | dept | varchar(16) | YES | | NULL | |

    +-------+-------------+------+-----+---------+----------------+

    4 rows in set (0.00 sec)

    删除后:

    mysql> alter table student2 drop index index_name;

    Query OK, 0 rows affected (2.08 sec)

    Records: 0 Duplicates: 0 Warnings: 0

    mysql> desc student2;

    +-------+-------------+------+-----+---------+----------------+

    | Field | Type | Null | Key | Default | Extra |

    +-------+-------------+------+-----+---------+----------------+

    | id | int(11) | NO | PRI | NULL | auto_increment |

    | name | char(20) | NO | | NULL | |

    | age | tinyint(2) | NO | | 0 | |

    | dept | varchar(16) | YES | | NULL | |

    +-------+-------------+------+-----+---------+----------------+

    4 rows in set (0.00 sec)

    为student2表的name列增加普通索引,索引的名字叫作index_name:例子

    mysql> alter table student2 add index index_name(name);

    Query OK, 0 rows affected (0.01 sec)

    Records: 0 Duplicates: 0 Warnings: 0

    mysql> show create table student2\G;

    *************************** 1. row ***************************

    Table: student2

    Create Table: CREATE TABLE `student2` (

    `id` int(11) NOT NULL AUTO_INCREMENT,

    `name` char(20) NOT NULL,

    `age` tinyint(2) NOT NULL DEFAULT '0',

    `dept` varchar(16) DEFAULT NULL,

    PRIMARY KEY (`id`),

    KEY `index_name` (`name`)

    ) ENGINE=MyISAM DEFAULT CHARSET=utf8

    1 row in set (0.00 sec)

    ERROR:

    No query specified

    注意: KEY `index_name` (`name`)  提示:访问数据量很大的时候,不适合建立普通索引,会影响用户访问,尽量选择业务低估时建立索引。

    展开全文
  • CREATE INDEX 语句用于在创建索引。...注释:更新一个包含索引需要比更新一个没有索引更多的时间,这是由于索引本身也需要更新。因此,理想的做法是仅仅在常常被搜索的列(以及)上面创建索引。 SQL...

    CREATE INDEX 语句用于在表中创建索引。

    在不读取整个表的情况下,索引使数据库应用程序可以更快地查找数据。

    索引

    您可以在表中创建索引,以便更加快速高效地查询数据。

    用户无法看到索引,它们只能被用来加速搜索/查询。

    注释:更新一个包含索引的表需要比更新一个没有索引的表更多的时间,这是由于索引本身也需要更新。因此,理想的做法是仅仅在常常被搜索的列(以及表)上面创建索引。

    SQL CREATE INDEX 语法

    在表上创建一个简单的索引。允许使用重复的值:

    CREATE INDEX index_name
    ON table_name (column_name)
    

    注释:"column_name" 规定需要索引的列。

    SQL CREATE UNIQUE INDEX 语法

    在表上创建一个唯一的索引。唯一的索引意味着两个行不能拥有相同的索引值。

    CREATE UNIQUE INDEX index_name
    ON table_name (column_name)

    CREATE INDEX 实例

    本例会创建一个简单的索引,名为 "PersonIndex",在 Person 表的 LastName 列:

    CREATE INDEX PersonIndex
    ON Person (LastName) 
    

    如果您希望以降序索引某个列中的值,您可以在列名称之后添加保留字 DESC

    CREATE INDEX PersonIndex
    ON Person (LastName DESC) 
    

    假如您希望索引不止一个列,您可以在括号中列出这些列的名称,用逗号隔开:

    CREATE INDEX PersonIndex
    ON Person (LastName, FirstName)

    转载于:https://www.cnblogs.com/forint/p/4074711.html

    展开全文
  • 可以在表格的一个或者多个列上创建索引,每个索引都会被起个名字。用户无法看到索引,它们只能被用来加速查询。注释:更新一个包含索引的需要比更新一个没有索引的更多的时间,这是由于索引本身也需要更新。因此...
  • 创建索引

    2017-04-28 14:14:48
    多列索引是在的多个字段上创建一个索引。该索引指向创建时对应的多个字段,用户可以通过这几个字段进行查询,要想应用该索引,用户必须使用这些字段中第一个字段 6空间索引: 使用SPATIAL参数可以设置索引为空间...
  • 以下是一个不完整的课程,我只把我需要的字段保留下来了,创建了两个单独的索引 idx_city_id 和idx_start_course_time CREATE TABLE `t_lesson` ( `id` BIGINT(20) NOT NULL AUTO_INCREMENT, `start_course_time...
  • CREATE INDEX 语句用于在中创建索引。 在不读取整个的情况下,索引使数据库应用程序可以更快地查找数据。 索引 您可以在中创建索引,以便更加快速高效地查询数据。 用户无法看到索引,它们...在创建一个...
  • 创建 索引

    2019-10-09 03:04:19
    可以在表格的一个或者多个列上创建索引,每个索引都会被起个名字。用户无法看到索引,它们只能被用来加速查询。 注释:更新一个包含索引的需要比更新一个没有索引的更多的时间,这是由于索引本身也需要更新。...
  • PRIMARY KEY主键索引不允许出现相同的值,且不能为NULL值,一个表只能有一个primary_key索引。fulltext index 全文索引上述三种索引都是针对列的值发挥作用,但全文索引,可以针对值中的某个单词,比如一篇文章中的...
  • 性能原因, 需要对一个表创建索引, 在索引维护界面竟然没有找到添加的按钮, 很不符合SAP的操作风格呀, 很少在SAP操作中使用右键的, 这里竟然只能用右键. 如下二图: SE11 
  • Oracle分区及分区索引-创建list分区创建list分区的语法如上,需要我们指定的:lcolumn:分区依赖列(注意:只能一个);lpartition:分区名称;lliteral:分区对应值(注意:每个分区可以对应多个值);ltablespace_clause:...
  • CREATE INDEX 语句用于在创建索引。 在不读取整个的情况下...注释:更新一个包含索引需要比更新一个没有索引更多的时间,这是由于索引本身也需要更新。因此,理想的做法是仅仅在常常被搜索的列(以及
  • 很久没有写SQL相关的文章了,主要是现在技术部分工比以前明确了。...在这次写的一个SQL查询中,体会到了在做join联接时,关联的键需要创建索引的重要性。 说明: 1:free_room,freeroom这两个表数据量都...
  • mysql创建索引

    千次阅读 2015-09-25 14:46:27
    CREATE INDEX 语句用于在创建...注释:更新一个包含索引需要比更新一个没有索引更多的时间,这是由于索引本身也需要更新。因此,理想的做法是仅仅在常常被搜索的列(以及)上面创建索引。SQL CREATE I
  • 1.Mysql索引的类型 普通索引(CREATE INDEX) 唯一索引 / 组合索引 / 复合索引索引列的值必须唯一(CREATE UNIQUE INDEX) ...主键索引(PRIMARY KEY),一个表只能有一个 全文索引(FULLTEXT INDEX),InnoD...
  • 1 创建主键索引查询数据库的内容,按主键查询是最快的,每个表只能一个主键,但是可以有多个普通索引列,主键列要求所有内容必须唯一,而索引列不要求内容唯一。我们无论建立主键索引还是普通索引,都要在表的对应...
  • 一、索引类型 1、普通索引:基本索引,没有任何限制 2、唯一索引:唯一索引是不允许其中任何两行具有相同索引值的...不能为NULL值,一个表只能有一个primary key索引。 4、全文索引 二、创建索引(三种方式)...
  • SQL 如何创建索引

    2017-08-10 11:23:18
    CREATE INDEX 语句用于在创建索引。...注释:更新一个包含索引需要比更新一个没有索引更多的时间,这是由于索引本身也需要更新。因此,理想的做法是仅仅在常常被搜索的列(以及)上面创建索引
  • 1 创建主键索引 查询数据库的内容,按主键查询是最快的,每个表只能一个主键,但是可以有多个普通索引列,主键列要求所有内容必须唯一,而索引列不要求内容唯一。我们无论建立主键索引还是普通索引,都要在表的...
  • 普通的MySQL用户利用表创建索引操作,以及利用查询的编写能够进行的优化。不过,还有一些只能由MySQL管理员和系统管理员来完成的优化,这些管理员在MySQL服务器或运行MySQL的机器上具有控制权。有的服务器参数直接...
  • 一、注意点1、索引视图所引用的基表必须在同一个数据库中,不是用unionall引用多个数据库的;2、创建索引视图时要加上with schemabinding;3、创建索引视图时要指定所属的架构;4、在创建索引视图的select语句时...
  • 创建索引视图

    2015-05-19 17:14:38
    SQL Server 2008 创建索引视图 SQL Server 2008 的索引视图似乎只能通过sql命令的方式创建, 暂未找到...2.创建完视图后, 必须紧跟着创建一个CLUSTERED聚集唯一索引. 3.只支持两部分命名的或UDF, 如 dbo.SalesOr

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,220
精华内容 488
关键字:

一个表只能创建一个索引