精华内容
下载资源
问答
  • 一个表可以有几个索引字段
    千次阅读
    2021-09-04 04:39:38

    前言

    mysql中一个表可以有多个唯一索引。

    如果能确定某个数据列只包含彼此各不相同的值,那么在为这个数据列创建索引时,就应该使用关键字UNIQUE把它定义为一个唯一索引。

    内容

    如果能确定某个数据列将只包含彼此各不相同的值,在为这个数据列创建索引的时候就应该用关键字UNIQUE把它定义为一个唯一索引。

    优点:

    1. 简化了MySQL对这个索引的管理工作,这个索引也因此而变得更有效率。
    2. MySQL会在有新记录插入数据表时,自动检查新记录的这个字段的值是否已经在某个记录的这个字段里出现过了;如果是,MySQL将拒绝插入那条新记录。

    总结

    也就是说,唯一索引可以保证数据记录的唯一性。事实上,在许多场合,人们创建唯一索引的目的往往不是为了提高访问速度,而只是为了避免数据出现重复。

    更多相关内容
  • 发现mysql一个表可以有几个唯一索引

    万次阅读 2018-04-26 09:07:44
    mysql一个表可以有多个唯一索引。如果能确定某个数据列将只包含彼此各不相同的值,在为这个数据列创建索引的时候就应该用关键字UNIQUE把它定义为一个唯一索引。这么做的好处:一是简化了MySQL对这个索引的管理工作,...

    mysql一个表可以有多个唯一索引

    如果能确定某个数据列将只包含彼此各不相同的值,在为这个数据列创建索引的时候就应该用关键字UNIQUE把它定义为一个唯一索引

    这么做的好处:

    一是简化了MySQL对这个索引的管理工作,这个索引也因此而变得更有效率。

    二是MySQL会在有新记录插入数据表时,自动检查新记录的这个字段的值是否已经在某个记录的这个字段里出现过了;如果是,MySQL将拒绝插入那条新记录。

    也就是说,唯一索引可以保证数据记录的唯一性。事实上,在许多场合,人们创建唯一索引的目的往往不是为了提高访问速度,而只是为了避免数据出现重复。

    展开全文
  • 对于复合索引:Mysql从左到右的使用索引中的字段一个查询可以只使用索引中的一部份,但只能是最左侧部分。例如索引是key index (a,b,c). 可以支持a | a,b| a,b,c 3种组合进行查找,但不支持 b,c进行查找 .当最左侧...

    联合索引又叫复合索引。对于复合索引:Mysql从左到右的使用索引中的字段,一个查询可以只使用索引中的一部份,但只能是最左侧部分。例如索引是key index (a,b,c). 可以支持a | a,b| a,b,c 3种组合进行查找,但不支持 b,c进行查找 .当最左侧字段是常量引用时,索引就十分有效。

    两个或更多个列上的索引被称作复合索引。

    利用索引中的附加列,您可以缩小搜索的范围,但使用一个具有两列的索引 不同于使用两个单独的索引。复合索引的结构与电话簿类似,人名由姓和名构成,电话簿首先按姓氏对进行排序,然后按名字对有相同姓氏的人进行排序。如果您知 道姓,电话簿将非常有用;如果您知道姓和名,电话簿则更为有用,但如果您只知道名不姓,电话簿将没有用处。

    所以说创建复合索引时,应该仔细考虑列的顺序。对索引中的所有列执行搜索或仅对前几列执行搜索时,复合索引非常有用;仅对后面的任意列执行搜索时,复合索引则没有用处。

    如:建立 姓名、年龄、性别的复合索引。

    create table test(

    a int,

    b int,

    c int,

    KEY a(a,b,c)

    );

    复合索引的建立原则:

    如果您很可能仅对一个列多次执行搜索,则该列应该是复合索引中的第一列。如果您很可能对一个两列索引中的两个列执行单独的搜索,则应该创建另一个仅包含第二列的索引。

    如上图所示,如果查询中需要对年龄和性别做查询,则应当再新建一个包含年龄和性别的复合索引。

    包含多个列的主键始终会自动以复合索引的形式创建索引,其列的顺序是它们在表定义中出现的顺序,而不是在主键定义中指定的顺序。在考虑将来通过主键执行的搜索,确定哪一列应该排在最前面。

    请注意,创建复合索引应当包含少数几个列,并且这些列经常在select查询里使用。在复合索引里包含太多的列不仅不会给带来太多好处。而且由于使用相当多的内存来存储复合索引的列的值,其后果是内存溢出和性能降低。

    复合索引对排序的优化:

    复合索引只对和索引中排序相同或相反的order by 语句优化。

    在创建复合索引时,每一列都定义了升序或者是降序。如定义一个复合索引:

    CREATE INDEX idx_example

    ON table1 (col1 ASC, col2 DESC, col3 ASC)

    其中 有三列分别是:col1 升序,col2 降序, col3 升序。现在如果我们执行两个查询

    1:

    Select col1, col2, col3 from table1 order by col1 ASC, col2 DESC, col3 ASC

    和索引顺序相同

    2:

    Select col1, col2, col3 from table1 order by col1 DESC, col2 ASC, col3 DESC

    和索引顺序相反

    查询1,2 都可以别复合索引优化。

    如果查询为:

    Select col1, col2, col3 from table1 order by col1 ASC, col2 ASC, col3 ASC

    排序结果和索引完全不同时,此时的 查询不会被复合索引优化。

    查询优化器在在where查询中的作用:

    如果一个多列索引存在于 列 Col1 和 Col2 上,则以下语句:Select   * from table where   col1=val1 AND col2=val2 查询优化器会试图通过决定哪个索引将找到更少的行。之后用得到的索引去取值。

    1. 如果存在一个多列索引,任何最左面的索引前缀能被优化器使用。所以联合索引的顺序不同,影响索引的选择,尽量将值少的放在前面。

    如:一个多列索引为 (col1 ,col2, col3)

    那么在索引在列 (col1) 、(col1 col2) 、(col1 col2 col3) 的搜索会有作用。

    SELECT * FROM tb WHERE col1 = val1

    SELECT * FROM tb WHERE col1 = val1 and col2 = val2

    SELECT * FROM tb WHERE col1 = val1 and col2 = val2 AND col3 = val3

    2. 如果列不构成索引的最左面前缀,则建立的索引将不起作用。

    如:

    SELECT * FROM tb WHERE col3 = val3

    SELECT * FROM tb WHERE col2 = val2

    SELECT * FROM tb WHERE col2 = val2 and col3=val3

    3. 如果一个 Like 语句的查询条件不以通配符起始则使用索引。

    如:%车 或 %车%   不使用索引。

    车%              使用索引。

    索引的缺点:

    1.       占用磁盘空间。

    2.       增加了插入和删除的操作时间。一个表拥有的索引越多,插入和删除的速度越慢。如 要求快速录入的系统不宜建过多索引。

    下面是一些常见的索引限制问题

    1、使用不等于操作符(<>, !=)

    下面这种情况,即使在列dept_id有一个索引,查询语句仍然执行一次全表扫描

    select * from dept where staff_num <> 1000;

    但是开发中的确需要这样的查询,难道没有解决问题的办法了吗?

    有!

    通过把用 or 语法替代不等号进行查询,就可以使用索引,以避免全表扫描:上面的语句改成下面这样的,就可以使用索引了。

    select * from dept shere staff_num < 1000 or dept_id > 1000;

    2、使用 is null 或 is not null

    使用 is null 或is nuo null也会限制索引的使用,因为数据库并没有定义null值。如果被索引的列中有很多null,就不会使用这个索引(除非索引是一个位图索引,关于位图索引,会在以后的blog文章里做详细解释)。在sql语句中使用null会造成很多麻烦。

    解决这个问题的办法就是:建表时把需要索引的列定义为非空(not null)

    3、使用函数

    如果没有使用基于函数的索引,那么where子句中对存在索引的列使用函数时,会使优化器忽略掉这些索引。下面的查询就不会使用索引:

    select * from staff where trunc(birthdate) = '01-MAY-82';

    但是把函数应用在条件上,索引是可以生效的,把上面的语句改成下面的语句,就可以通过索引进行查找。

    select * from staff where birthdate < (to_date('01-MAY-82') + 0.9999);

    4、比较不匹配的数据类型

    比较不匹配的数据类型也是难于发现的性能问题之一。

    下面的例子中,dept_id是一个varchar2型的字段,在这个字段上有索引,但是下面的语句会执行全表扫描。

    select * from dept where dept_id = 900198;

    这是因为oracle会自动把where子句转换成to_number(dept_id)=900198,就是3所说的情况,这样就限制了索引的使用。

    把SQL语句改为如下形式就可以使用索引

    select * from dept where dept_id = '900198';

    恩,这里还有要注意的:

    比方说有一个文章表,我们要实现某个类别下按时间倒序列表显示功能:

    SELECT * FROM articles WHERE category_id = ... ORDER BY created DESC LIMIT ...

    这样的查询很常见,基本上不管什么应用里都能找出一大把类似的SQL来,学院派的读者看到上面的SQL,可能会说SELECT *不好,应该仅仅查询需要的字段,那我们就索性彻底点,把SQL改成如下的形式:

    SELECT id FROM articles WHERE category_id = ... ORDER BY created DESC LIMIT ...

    我们假设这里的id是主键,至于文章的具体内容,可以都保存到memcached之类的键值类型的缓存里,如此一来,学院派的读者们应该挑不出什么毛病来了,下面我们就按这条SQL来考虑如何建立索引:

    不考虑数据分布之类的特殊情况,任何一个合格的WEB开发人员都知道类似这样的SQL,应该建立一个”category_id, created“复合索引,但这是最佳答案不?不见得,现在是回头看看标题的时候了:MySQL里建立索引应该考虑数据库引擎的类型!

    如果我们的数据库引擎是InnoDB,那么建立”category_id, created“复合索引是最佳答案。让我们看看InnoDB的索引结构,在InnoDB里,索引结构有一个特殊的地方:非主键索引在其BTree的叶节点上会额外保存对应主键的值,这样做一个最直接的好处就是Covering Index,不用再到数据文件里去取id的值,可以直接在索引里得到它。

    如果我们的数据库引擎是MyISAM,那么建立"category_id, created"复合索引就不是最佳答案。因为MyISAM的索引结构里,非主键索引并没有额外保存对应主键的值,此时如果想利用上Covering Index,应该建立"category_id, created, id"复合索引。

    唠完了,应该明白我的意思了吧。希望以后大家在考虑索引的时候能思考的更全面一点,实际应用中还有很多类似的问题,比如说多数人在建立索引的时候不从Cardinality(SHOW INDEX FROM ...能看到此参数)的角度看是否合适的问题,Cardinality表示唯一值的个数,一般来说,如果唯一值个数在总行数中所占比例小于20%的话,则可以认为Cardinality太小,此时索引除了拖慢insert/update/delete的速度之外,不会对select产生太大作用;还有一个细节是建立索引的时候未考虑字符集的影响,比如说username字段,如果仅仅允许英文,下划线之类的符号,那么就不要用gbk,utf-8之类的字符集,而应该使用latin1或者ascii这种简单的字符集,索引文件会小很多,速度自然就会快很多。这些细节问题需要读者自己多注意,我就不多说了。

    展开全文
  • 索引使用简介、 关于索引的知识要写出运行效率高的sql,需要对索引的机制一定了解,下面对索引的基本知识做介绍。1、 索引的优点和局限索引可以提高查询的效率,但会降低dml操作的效率。所以建立索引时需要...

    索引使用简介

    一、 关于索引的知识

    要写出运行效率高的sql,需要对索引的机制有一定了解,下面对索引的基本知识做一介绍。

    1、 索引的优点和局限

    索引可以提高查询的效率,但会降低dml操作的效率。

    所以建立索引时需要权衡。对于dml操作比较频繁的表,索引的个数不宜太多。

    2、 什么样的列需要建索引?

    经常用于查询、排序和分组的列(即经常在where、order或group by子句中出现的列)。

    3、 主键索引和复合索引

    对于一张表的主键,系统会自动为其建立索引。

    如果一张表的几列经常同时作为查询条件,可为其建立复合索引。

    4、 建立索引的语句

    create index i_staff on staff (empno);

    create index i_agent on agent (empno, start_date);

    5、 删除索引的语句

    drop index I_staff;

    drop index I_agent;

    6、 查询索引的语句 法一:利用数据字典

    表一:all_indexes 查看一张表有哪些索引以及索引状态是否有效

    主要字段: index_name, table_name, status

    例如:select index_name, status

    from all_indexes

    where table_name=’STAFF_INFO’;

    INDEX_NAME STATUS

    --------------------- -----------

    I_STAFF VALID

    表二:all_ind_columns 查看一张表在哪些字段上建了索引

    主要字段: table_name, index_name, column_name, column_position

    例如: select index_name, column_name, column_position

    from all_ind_columns

    where table_name=’AGENT’

    INDEX_NAME COLUMN_NAME COLUMN_POSITON

    --------------------- ----------------------- --------------------------

    I_AGENT EMPNO 1

    I_AGENT START_DATE 2

    由此可见,agent表中有一个复合索引(empno, start_date )

    法二:利用toad工具

    toad用户界面比sql*plus友好,并且功能强大。你可以在toad编辑器中键入表名,按F4,便可见到这张表的表结构以及所有索引列等基本信息。

    7、 索引的一些特点

    1): 不同值较多的列上可建立检索,不同值少的列上则不要建。比如在雇员表的“性别”列上只有“男”与“女”两个不同值,因此就没必要建立索引。如果建立索引不但不会提高查询效率,反而会严重降低更新速度。

    2): 如果在索引列上加表达式,则索引不能正常使用

    例如:b1,c1分别是表b,c的索引列

    select * from b where b1/30<1000;

    select * from c where to_char(c1,’YYYYMMDD HH24:MI:SS’)= ‘20020314:01:01’;

    以上都是不正确的写法

    3): where子句中如果使用in、or、like、!=,均会导致索引不能正常使用例如:select * from b where b1=30or b1=40;4): 使用复合索引进行查询时必须使用前置列

    例如表a上有一个复合索引(c1,c2,c3),则c1为其前置列

    如果用c1或c1+c2或c1+c2+c3为条件进行查询,则该复合索引可以发挥作用,反之,用c2或c3或c2+c3进行查询,则该索引不能起作用。

    二. 书写sql注意事项:

    1、 避免给sql语句中引用的索引列添加表达式:

    典型实例:

    b1,c1分别是表b,c的索引列:

    1) select * from b where b1/30< 1000 ;

    2) select * from c where to_char(c1,’YYYYMMDD HH24:MI:SS’)= ‘20020314:01:01’;

    替代方案:

    1) select * from b where b1 < 30000;

    2) select * from c where c1= to_date(‘2002030114:01:01’, ‘YYYYMMDD HH24:MI:SS’);

    注:在lbs中有两个重要字段,pol_info中的undwrt_date和prem_info中的payment_date,这两个日期是带时分秒的,所以经常有同事用to_char 来查询某一时间段的数据。

    例如:select count(*) from pol_info where to_char(undwrt_date,’YYYYMMDD’)=’20020416’;select count(*) from prem_info where to_char(undwrt_date,’YYYYMM’)=’200203’;替代方案:

    select count(*) from pol_info

    where undwrt_date>=to_date(’20020416’,’YYYYMMDD’) and

    undwrt_date select count(*) from prem_info

    where payment_date>=to_date(’20020301’,’YYYYMMDD’) and

    payment_date

    2、 避免在where子句中使用in、or、like、!=

    典型实例:

    a1是a表上的索引列:

    1) select * from a

    where ( a1 = ‘0’ and ...) or (a1 = ‘1’ and ...);

    2) select count(*) from a where a1 in (‘0’,’1’) ;

    替代方案:

    1) select * from a where a1 = ‘0’ and ...

    union

    select * from a where a1 = ‘1’ and ...

    2) select count(*) from a where a1 = ‘0’;

    select count(*) from a where a1 = ‘1’;

    然后做一次加法运算;或者直接用存储过程来实现;

    小结:

    对字段使用了 ‘in,or,like’ 做条件、对字段使用了不等号 ‘!=’,均会使索引失效;如果不产生大量重复值,可以考虑把子句拆开;拆开的子句中应该包含索引,或者使用union连结符代替。另一种方式是使用存储过程,它使SQL变得更加灵活和高效。

    3、 建立适当的索引

    曾经接过开发的一个统计sql, select … from tablea where cola=… and …

    运行效率非常慢,经查tablea数据量巨大,再查all_ind_columns,发现cola是tablea的一个复合索引中的一列,但不是前置列。象这种情况,就需要与开发商量,是否针对cola建一个索引。

    4、 like和substr

    对于‘like’和‘substr’,其效率并没有多大分别。但是,当所搜索的值不存在时,使用‘like’的速度明显大于‘substr’。

    所以:select * from a where substr(a1,1,4) = '5378' 可以用like替代

    select * from a where a1 like ‘5378%’;

    5、 写where条件时,有索引字段的判断在前,其它字段的判断在后;如果where条件中用到复合索引,按照索引列在复合索引中出现的顺序来依次写where条件;

    6、使用多表连接时,在from子句中,将记录数少的表放在后面,可提高执行效率;

    7、避免使用not in

    not in 是效率极低的写法,尽量使用minus或外连接加以替代

    典型实例:

    1) select col1 from tab1 where col1 not in (select col1 from tab2);

    2) select sum(col2) from tab1 where col1 not in (select col1 from tab2);

    替代方案

    select col1 from tab1 minus select col1 from tab2;

    select sum(a.col2) from tab1 a, tab2 b

    where a.col1=b.col2(+) and b.col1 is null;

    8、多表查询时,如果其中一个表的记录数量明显大于其他表,则可以先对此表进行查询后,再与其他小表进行表连接。

    典型实例:

    select a.plan_code, b.dno, c,tno, sum(a.tot_modal_prem),

    from prem_info a, dept_ref b, plan_type c

    where substr(a.deptno,1,7) = substr(b.deptno,1,7)

    and a.plan_code = c.plan_code

    group by b.dno, c.tno, a.plan_code;

    替代方案:

    select b.dno, c.tno, a.plan_code, a.tot_amount

    from (select plan_code, deptno, sum(tot_modal_prem) tot_amount

    from prem_info

    group by deptno, plan_code) a

    dept_ref b,

    plan_type c

    where substr(a.deptno,1,7) = substr(b.deptno,1,7)

    and a.plan_code = c.plan_code

    group by b.dno, c.tno, a.plan_code;

    小结:

    由于prem_info表的记录数远远大于dept_ref表和plan_type表中的记录数, 所以首先从prem_info表中查询需要的记录,此时记录数已经被大量缩小,然后再和其他两个表连接,速度会得到很大改善!

    9、查询数量较大时,使用表连接代替IN,EXISTS,NOT IN,NOT EXISTS等。

    典型实例:

    a、使用IN:

    select sum(col2) from tab1 where col1 in (select col1 from tab2);

    使用EXISTS::

    select sum(col2) from tab1 a

    where exists ( select * from tab2 where col1=a.col1);

    b、使用NOT IN:

    select sum(col2) from tab1 where col1 not in (select col1 from tab2);

    使用NOT EXISTS:

    select sum(col2) from tab1 a

    where not exists ( select * from tab2 where col1=a.col1);

    替代方案:

    a、使用连接:

    select sum(a.col2) from tab1 a,tab2 b where a.col1=b.col2;

    b、使用外连接:

    select sum(a.col2) from tab1 a,tab2 b

    where a.col1=b.col2(+) and b.col1 is null;

    \•索引是建立在表的一列或多个列上的辅助对象,它有利于快速访问表的数据。

    •索引由于其内在的结构,它具有某些内在的开销,这些开销依赖于为了检索由索引中ROWID指定的行所访问的表中的块数,并且这个开销可能会超过进行全表扫描的成本。

    聚集索引确定表中数据的物理顺序。聚集索引类似于电话簿,按姓氏排列数据。由于聚集索引规定数据在表中的物理存储顺序,因此一个表只能包含一个聚集索引。但该索引可以包含多个列(组合索引),就像电话簿按姓氏和名字进行组织一样。

    聚集索引对于那些经常要搜索范围值的列特别有效。使用聚集索引找到包含第一个值的行后,便可以确保包含后续索引值的行在物理相邻。例如,如果应用程序执行的一个查询经常检索某一日期范围内的记录,则使用聚集索引可以迅速找到包含开始日期的行,然后检索表中所有相邻的行,直到到达结束日期。这样有助于提高此类查询的性能。同样,如果对从表中检索的数据进行排序时经常要用到某一列,则可以将该表在该列上聚集(物理排序),避免每次查询该列时都进行排序,从而节省成本。

    当索引值唯一时,使用聚集索引查找特定的行也很有效率。例如,使用唯一雇员 ID 列 emp_id 查找特定雇员的最快速的方法,是在 emp_id 列上创建聚集索引或 PRIMARY KEY 约束。

    非聚集索引与聚集索引一样有 B 树结构,但是有两个重大差别:

    数据行不按非聚集索引键的顺序排序和存储。非聚集索引的叶层不包含数据页。 相反,叶节点包含索引行。每个索引行包含非聚集键值以及一个或多个行定位器,这些行定位器指向有该键值的数据行(如果索引不唯一,则可能是多行)。 非聚集索引可以在有聚集索引的表、堆集或索引视图上定义。在 Microsoft®SQL Server™ 2000 中,非聚集索引中的行定位器有两种形式:

    如果表是堆集(没有聚集索引),行定位器就是指向行的指针。该指针用文件标识符 (ID)、页码和页上的行数生成。整个指针称为行 ID。如果表没有聚集索引,或者索引在索引视图上,则行定位器就是行的聚集索引键。如果聚集索引不是唯一的索引,SQL Server 2000 将添加在内部生成的值以使重复的键唯一。用户看不到这个值,它用于使非聚集索引内的键唯一。SQL Server 通过使用聚集索引键搜索聚集索引来检索数据行,而聚集索引键存储在非聚集索引的叶行内。 由于非聚集索引将聚集索引键作为其行指针存储,因此使聚集索引键尽可能小很重要。如果表还有非聚集索引,请不要选择大的列作为聚集索引的键。

    关于索引(转)

    索引的三個問題

    索引( Index )是常见的数Database 的性能。虽然有许多,还是有不少的人对它存在误解Oracle 8.1.7 OPS on HP N se使用不同的方法后,数据的比较明白事情的关键。 据库对象,它的设置好坏、使用是否资料讲索引的用法, DBA 和 Develo,因此针对使用中的常见问题,讲三ries ,示例全部是真实数据,读者不。本文所讲基本都是陈词滥调,但是 得当,极大地影响数据库应用程序和per 们也经常与它打交道,但笔者发现个问题。此文所有示例所用的数据库是需要注意具体的数据大小,而应注意在笔者试图通过实际的例子,来真正让您

    第一讲、索引并非总是最佳选择

    如果发现Oracle 在有索引,Oracle 确实会选择全表扫描 的情况下,没有使用索引,这并不是(Full Table Scan),而非索引扫描 Oracle 的优化器出错。在有些情况下(Index Scan)。这些情况通常有:

    1. 表未做statistics, 或 者 statistics 陈旧,导致 Oracle 判断失误。

    2. 根据该表拥有的记录数和数据块数,实际上全表扫描要比索引扫描更快。

    对第1种情况,最常见的例子,是以下这句sql 语句:

    select count(*) from mytable;

    在未作statistics 之前,它使用全表扫描,statistics 之后,使用的是 INDEX (FAST FULL S得不好,也会导致Oracle 不使用索引。 需要读取6000多个数据块(一个数据块是8k), 做了CAN) ,只需要读取450个数据块。但是,statistics 做

    第2种情况就要复杂得多。一般概念上都认为扫描快。为了讲清楚这个问题,这里先介绍一下Or:CF(Clustering factor) 和 FF(Filtering fact 索引比表快,比较难以理解什么情况下全表扫描要比索引acle 在评估使用索引的代价(cost)时两个重要的数据or).

    CF: 所谓 CF, 通俗地讲,就是每读入一个索引块,要对应读入多少个数据块。

    FF: 所谓 FF, 就是该sql 语句所选择的结果集,占总的数据量的百分比。

    大约的计算公式是:FF * (要读入的数据块块数。需要读入全表扫描需要读入的数据块数等 CF + 索引块个数) ,由此估计出,的数据块越多,则 cost 越大,Orac于该表的实际数据块数) 一个查询, 如果使用某个索引,会需le 也就越可能不选择使用 index. (

    其核心就是, CF 可能会比实际的数据块数量建立时,索引中的记录与表中的记录有良好的对应对应关系越来越乱,CF 也越来越大。此时需要 DB 大。CF 受到索引中数据的排列方式影响,通常在索引刚关系,CF 都很小;在表经过大量的插入、修改后,这种A 重新建立或者组织该索引。

    如果某个sql 语句以前一直重新整理该索引了。 使用某索引,较长时间后不再使用, 一种可能就是 CF 已经变得太大,需要

    FF 则是Oracle 根据 stati,最大值是409654,考虑以下sq stics 所做的估计。比如, mytablesl 语句: 表有32万行,其主键myid的最小值是1

    Select * from mytables where myid>=1; 和

    Select * from mytables where myid>=400000

    这两句看似差不多的 sql 者的 FF 可能只有 1%。如果它实际上,在我们的数据库上的测 语句,对Oracle 而言,却有巨大的的CF 大于实际的数据块数,则Oracl试验证了我们的预测. 以下是在HP 差别。因为前者的 FF 是100%, 而后e 可能会选择完全不同的优化方式。而

    第二讲、索引也有好坏

    索引有 B tree 索引, Bit全称是Balanced , 其意义是,有一个字段(Single column),Function-based index. 许多de map 索引, Reverse b tree 索引,从 tree 的 root 到任何一个leaf 也可以有多个字段(Composite),veloper 都倾向于使用单列B 树索引 等。最常用的是 B tree 索引。 B 的,要经过同样多的 level. 索引可以只最多32个字段,8I 还支持 。

    所谓索引的好坏是指:

    1,索引不是越多越好。特别是大量从来或者个索引即会降低性能,而且在一个sql 中, Oracl 几乎不用的索引,对系统只有损害。OLTP系统每表超过5e 从不能使用超过 5个索引。

    2,很多时候,单列索引不如复合索引有效率。

    3,用于多表连结的字段,加上索引会很有作用。

    那么,在什么情况下单列索所查询的列,全部都出现在复合使用多个单列索引要快得多。( 引不如复合索引有效率呢?有一种情索引中时,此时由于 Oracle 只需要此时,这种优化方式被称为 Index o 况是显而易见的,那就是,当sql 语句查询索引块即可获得所有数据,当然比nly access path)

    第三讲、索引再好,不用也是白搭

    抛开前面所说的,假设你设不用,那么,需要做的第一件事 置了一个非常好的索引,任何傻瓜都情,是审视你的 sql 语句。 知道应该使用它,但是Oracle 却偏偏

    Oracle 要使用一个索引,有一些最基本的条件:

    1, where 子句中的这个字段,必须是复合索引的第一个字段;

    2, where 子句中的这个字段,不应该参与任何形式的计算

    具体来讲,假设一个索引是按 f1, f2, f3的= : var2, 则因为 f2 不是索引的第1个字段,无 次序建立的,现在有一个 sql 语句, where 子句是 f2 法使用该索引。

    第2个问题,则在我们之中非常严重。以下是从 实际系统上面抓到的几个例子:

    Select jobid from mytabs where isReq='0' and to_date (updatedate) >= to_Date ( '2001-7-18', 'YYYY-MM-DD');

    以上的例子能很容易地进行和 内存资源。 改进。请注意这样的语句每天都在我 们的系统中运行,消耗我们有限的cpu

    除了1,2这两个我们必须牢记于心的原则外,。这里我只讲哪些操作或者操作符会显式(explic 还应尽量熟悉各种操作符对 Oracle 是否使用索引的影响itly)地阻止 Oracle 使用索引。以下是一些基本规则:

    1, 如果 f1 和 f2 是同一个表的两个字段,则 f1>f2, f1>=f2, f1

    2, f1 is null, f1 is no t null, f1 not in, f1 !=, f1 lik e ‘%pattern%’;

    3, Not exist

    4, 某些情况下,f1 in 也会不用索引;

    对于这些操作,别无办法,许可以将 in 操作改成 比较操 只有尽量避免。比如,如果发现你的作 + union all。笔者在实践中发现 sql 中的 in 操作没有使用索引,也很多时候这很有效。

    但是,Oracle 是否真正使用索引,使用索引,对所写的复杂的 sql, 在将它写入应用程序之前Oracle 对该 sql 的解析(plan),可以明确地看是否真正有效,还是必须进行实地的测验。合理的做法是,先在产品数据库上做一次explain . explain 会获得到 Oracle 是如何优化该 sql 的。

    如果经常做 explain, 就会划往往不尽如人意。事实上,将然这已经是题外话了。发现,喜爱写复杂的 sql 并不是个复杂的 sql 拆开,有时候会极大地好习惯,因为过分复杂的sql 其解析计提高效率,因为能获得很好的优化。当没有对name建索引之前,oracle使用全表扫描。时间长短视数据库参数db_file_multiblock_read_count的设置,一次读取db_file_multiblock_read_count*db_block_size(db_cache_dize)的数据.

    建立索引之后,oracle使用index range scan,一次读取一条索引。

    展开全文
  • 创建时报错: > 1118 - Row size too large (> 8126). Changing some columns to TEXT or BLOB may help. In current row format, ...● InnoDB 最多只能1000个字段字段长度加起来如果超过65535,MyS.
  • 62616964757a686964616fe58685e5aeb931333366306538外键就是自己设置了也即可以有多个,可以设置除主键以外的其他字段全部是外键的。数据库的每张只能有一个主键,不可能有多个主键。所谓的一张多个主键,我们称...
  • MYSQL 引擎innodb ,设置了唯一索引的列值 允许 多NULL值存在。 示例: 字段 userCardNum 添加了唯一索引 证实是允许存在的多NULL值数据的: 原由: 因为这里 NULL 的定义 ,是指 未知值。 所以多...
  • Oracle多个字段联合索引保证唯一性

    千次阅读 2021-09-26 16:00:30
    今天在开发过程中遇到了需要两个字段联合保证唯一性,所以查阅了一些资料和博客,梳理一下以便之后... 唯一约束:唯一约束保证在一个字段或者一组字段里的数据与中其它行的数据相比是唯一的(联合字段中,可以包含...
  • mysql多字段唯一索引

    千次阅读 2021-01-19 06:32:34
    项目中需要用到联合唯一索引:例如:以下需求:每人每天只有可能产生条记录:处了程序约定之外,数据库本身也可以设定:例如:useruserID,userName两个字段,如果不希望2条一模一样的记录,需要给user添加...
  • 可以创建多个索引嘛? 可以创建多个索引的。 需要开发人员根据实际的用途以及数据库中记录的情况,来进行判断。 通常来说,的索引越多,其查询的速度也就越快。但是,的insert/update速度则会降低。这主要是...
  • 一个表最多16个索引,最大索引长度256字节。 索引一般不明显影响插入性能(大量小数据例外),因为建立索引的时间开销是O(1)或者O(logN)。
  • mysql可以设置联合唯一索引吗?

    千次阅读 2021-01-18 21:11:58
    mysql可以设置联合唯一索引,方法:使用“Alter table 表名 add UNIQUE index 索引名 (字段1,字段2)”语句来设置,它会删除重复的记录,保留条,然后建立联合唯一索引。联合唯一索引项目需要将某个的某两个字段...
  • 哪些字段适合建索引

    千次阅读 2020-07-31 17:57:36
    1、的主键、外键必须有索引; 2、数据量超过300的应该有索引; 3、经常与其他进行连接的,在连接字段上应该建立索引; 4、经常出现在Where子句中的字段,特别是大字段,应该建立索引; 5、索引应该建在...
  • # 不走索引 select * from t1 where date(c) ='2019-05-21'; # 走索引 select * from t1 where c>='2019-05-21 00:00:00' and c<='2019-05-21 23:59:59'; 补充: c 字段存储值为 (datetime) 2019-05-22...
  • 发现好次下面这样的话:如果经常需要同时对两个字段进行AND查询,那么使用两个单独索引不如建立一个复合索引,因为两个单独索引通常数据库只能使用其中一个,而使用复合索引因为索引本身就对应到两个字段上的,效率...
  • MySQL大数据增加字段索引实现

    万次阅读 2017-11-16 14:44:15
    需要在一张1800万数据量的中添加加一个字段并添加索引,但是直接添加会导致mysql崩溃或者锁时间太长影响用户操作,所以需要利用其他的方法进行添加,这篇文章主要给大家介绍了MySQL中大数据增加字段,增加索引...
  • 解决办法:唯一索引可在索引列插入多次null email可以有多条email为null的记录,将冲突的字段设置为null,解决 在sql server中,唯一索引字段不能出现多null值 在mysql 的innodb引擎中,是允许在唯一索引的字段中...
  • 背景 索引:IDX(b,c) sql select id where b = xx; select id where c = xx; 上面的两句sql会走b,c的联合索引吗? 答案是第一条会走,第二条不会 ...只要没有使用联合索引的第一个字段,则不会走联合索引 ...
  • oracle中多个字段组成唯一索引约束

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

    万次阅读 2016-07-12 16:11:08
    原文:http://mp.weixin.qq.com/s?__biz=MzAwMjkyMjEwNg==&mid=2247483785&idx=1&sn=1d90a44915d1028c6dc150367e1af033#rd ...*如果我将下面中的varchar(200),修改成text(或blob):报错变为另一个:*
  • 为时间字段索引

    千次阅读 2020-03-24 18:29:58
    文章目录为时间字段索引(待更进)、问题1、描述:日期不一致2、原因:时区不同3、解决方法: 时区修改二、datetime和varchar类型效率比较1、背景2、开始三、时间字段索引1、聚集索引2、非聚集索引3、时间字段...
  • 对于SQL调优,要调就调到极致,小编并不是处女座,而是因为在一个并发量很大的业务系统中,对于频繁执行的单条SQL性能的提升,可能对整体数据库的性能提升都很大的意义。 但是遇到order by字段后面的字段,特别是...
  • 那些字段适不适合建索引

    千次阅读 2021-02-02 14:36:59
    数据库建立索引常用的规则如下:的主键、外键必须有索引;数据量超过300的应该有索引;经常与其他进行连接的,在连接字段上应该建立索引;经常出现在Where子句中的字段,特别是大字段,应该建立索引;...
  • 2、查询时使用联合索引一个字段,如果这个字段在联合索引中所有字段的第一个,那就会用到索引,否则就无法使用到索引。 3、联合索引IDX(字段A,字段B,字段C,字段D),当仅使用字段A查询时,索引IDX就会使用到;如果...
  • MySQL中四种方式给字段添加索引

    千次阅读 2021-08-24 18:04:54
    该语句添加一个主键,这意味着索引值必须是唯一的,且不能为NULL。 添加唯一索引 ALTER TABLE tbl_name ADD UNIQUE index_name (col_list); 这条语句创建索引的值必须是唯一的。 添加普通索引 ALTER TABLE tbl_...
  • 例如你有一个 学生字段包含 学号, 班级, 姓名,性别, 出生年月日。 你创建一个 组合索引 ( 班级, 姓名) 那么 SELECT * FROM 学生 WHERE 班级='2010级3班' AND 姓名='张三' 将使用索引. SELECT * FROM...
  • Mysql哪些字段适合建立索引

    千次阅读 2020-03-24 15:38:38
    1、的主键、外键必须有索引; 2、数据量超过300的应该有索引; 3、经常与其他进行连接的,在连接字段上应该建立索引; 4、经常出现在Where子句中的字段,特别是大字段,应该建立索引; 5、索引应该建在...
  • 在一般情况下,它们是一对一的关系:即一张原始单据对应且只对应一个实体。  在特殊情况下,它们可能是一对多或多对一的关系,即一张原始单证对应多个实体,或多张原始单证对应一个实体。  这里的实体可以理解为...
  • mysql的最多可设置多少字段

    万次阅读 热门讨论 2019-11-12 20:29:17
    最近在开发的时候,遇到一个报错:Can't create tablexxx(errno: 185 "Too many columns")根据英文,意思是字段太多了,那么mysql的数据最多能多少列呢?       怀着虔诚的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 329,886
精华内容 131,954
关键字:

一个表可以有几个索引字段