精华内容
下载资源
问答
  • BGP邻居建立失败查询思路

    千次阅读 2019-10-28 17:11:08
    bgp邻居建立失败查询思路: 1. 常见原因 BGP邻居无法建立是指BGP邻居状态无法到达Established状态。 本类故障的常见原因主要包括: BGP报文转发不通。 ACL过滤了TCP的179端口。 邻居的Router ID冲突。 配置的邻居的...

    bgp邻居建立失败查询思路:

    1. 常见原因

    BGP邻居无法建立是指BGP邻居状态无法到达Established状态。

    本类故障的常见原因主要包括:

    • BGP报文转发不通。
    • ACL过滤了TCP的179端口。
    • 邻居的Router ID冲突。
    • 配置的邻居的AS号错误。
    • 用Loopback口建立邻居时没有配置peer connect-interface命令。
    • 用Loopback口建立EBGP邻居未配置peer ebgp-max-hop命令。
    • peer valid-ttl-hops配置错误。
    • 对端发送的路由数量是否超过peer route-limit命令设定的值。
    • 对端配置了peer ignore命令。
    • 两端的地址族不匹配。

    2. 故障诊断流程

    在配置BGP协议后发现BGP邻居无法建立。

    可按照故障诊断流程图1-1排除故障。

    图1-1 BGP邻居无法建立故障诊断流程图

    3. 故障处理步骤

    背景信息说明:

    ​ 请保存以下步骤的执行结果,以便在故障无法解决时快速收集和反馈信息。

    操作步骤:

    步骤 1

    使用ping命令检测BGP邻居之间是否可以Ping通

    • 如果可以Ping通,则说明BGP邻居之间有可达的路由并且链路传输也没有问题,请执行步骤2。
      说明 请使用命令ping–a source-ip-address –s packetsize host来检测两端的互通性,因为带源地址可以同时检测两端路由是否正常,指定ping的字节可以检查大包在链路上传输是否正常。
    • 如果不能Ping通,请参见19.2.6.1.1 Ping不通问题的定位思路检查两端的路由表中是否存在对端路由。

    步骤 2

    检查是否配置ACL禁止TCP的179端口

    在两端执行display acl all命令查看是否禁止TCP的179端口。

    <Huawei>display acl all 
    
    Total nonempty ACL number is 1 
    
    Advanced ACL 3001, 2 rules 
    
    Acl's step is 5 
    
    rule 5 deny tcp source-port eq bgp 
    
    rule 10 deny tcp destination-port eq bgp
    
    • 如果有禁止TCP的179端口的ACL,请执行undo rule rule-id destination-port和undo rule rule-id source-port命令取消配置。
    • 如果没有禁止TCP的179端口的ACL,请执行步骤3。

    步骤 3

    检查邻居的Router ID是否冲突

    ​ 在两端分别查看无法建立的BGP邻居的情况,例如ipv4单播邻居无法建立可以执行display bgp peer命令,查看Router ID是否冲突。显示Router ID信息的命令行示例如下,该例中本端的Router ID是223.5.0.109。

    <Huawei>display bgp peer 
    
    BGPlocal router ID : 223.5.0.109 
    
    Local AS number : 41976
    
    Total number of peers : 12 Peers in established state : 4 
    
    Peer V AS MsgRcvd MsgSent OutQ Up/Down State PrefRcv 
    
    8.9.0.8 4 100 1601 1443 0 23:21:56 Established 10000 
    
    9.10.0.10 4 200 1565 1799 0 23:15:30 Established 9999
    

    说明

    查看BGP-VPNv4地址族或BGP-VPN实例地址族的邻居可以使用命令display bgp vpnv4 all peer。

    • 如果Router ID冲突,请在BGP视图下运行命令router id将Router ID修改为不同(一般会用Loopback口的地址作为本端的Router ID)。
    • 如果Router ID没有冲突,请执行步骤4。

    步骤 4

    检查邻居AS号配置是否正确

    ​ 在两端分别执行display bgp peer,检查邻居的AS号是否是对端的AS号。

    <Huawei>display bgp peer 
    BGP local router ID : 223.5.0.109 
    
    LocalAS number : 41976 
    
    Total number of peers : 12 Peers in established state : 4 
    
    Peer V AS MsgRcvd MsgSent OutQ Up/Down State PrefRcv 
    
    8.9.0.8 4 100 1601 1443 0 23:21:56 Established 10000 
    
    9.10.0.10 4 200 1565 1799 0 23:15:30 Established 9999
    

    说明

    ​ 查看BGP-VPNv4地址族或BGP-VPN实例地址族的邻居可以使用命令display bgp vpnv4 all peer。

    • 如果AS号配置错误,请将AS号配置为对端的AS。
    • 如果AS号配置没有错误,请执行步骤5。

    步骤 5

    检查BGP配置是否影响邻居建立

    ​ 通过displaycurrent-configuration configuration bgp查看BGP的配置,进行如下检查。

    检查项 说明
    peer connect-interface interface-type interface-number 如果邻居两端使用Loopback口建立邻居,则需要使用命令peer connect-interface指定相应的Loopback口为发送BGP报文的源接口。
    peer ebgp-max-hop hop-count 如果直连设备用Loopback口建立EBGP邻居,或者非直连多跳设备建立EBGP邻居,则需要配置命令peer ebgp-max-hop指定允许的最大跳数hop-count。 直连设备使用Loopback口建立连接时,hop-count只要大于1即可。 非直连设备建立连接时需要指定hop-count为相应的跳数。
    peer valid-ttl-hops hops 如果有该配置,请确认peer valid-ttl-hops hops是否正确:如果配置为hops,则被检测的报文的TTL值有效范围为[255–hops+1, 255]。其中hops是BGP会话两端之间的跳数值,直连设备之间的hops为1。 说明 命令peer valid-ttl-hops的配置是对称的,即需要在BGP会话两端同时使能该命令。
    peer route-limit limit 如果有该配置时,请确认对端发送的路由数量是否超过peer route-limit limit,其中limit表示限制的路由数量。如果是,则需要降低对端发送过来的路由数量,并在本端使用reset bgp ip-address命令复位相应的BGP连接来触发BGP重新建立连接。
    peer ignore 如果对端配置了peer ignore,说明由于某种原因对端暂时不想和本端建立邻居。如果想建立邻居时,执行undo peer ignore命令去使能对端的配置即可。
    地址族能力 请检查BGP会话两端的地址族能力是否匹配。例如,建立BGP VPNv4邻居时,需要两端都要在BGP-VPNv4地址族下配置命令peer enable。如果一端已配置而另一端没有配置时,没有配置的一端BGP邻居状态为“No neg”。

    步骤 6

    如果故障仍未排除,请收集如下信息,并联系技术支持人员。

    • 上述步骤的执行结果。

    PNv4邻居时,需要两端都要在BGP-VPNv4地址族下配置命令peer enable。如果一端已配置而另一端没有配置时,没有配置的一端BGP邻居状态为“No neg”。 |

    步骤 6

    如果故障仍未排除,请收集如下信息,并联系技术支持人员。

    • 上述步骤的执行结果。

    • 设备的配置文件、日志信息、告警信息。

    展开全文
  • 对于复杂的查询语句,为了让oracle查询更快一些,可以建立索引,是对where条件字段建立索引好些?还是查询结果字段建立索引好些?
  • 需求: 有多张 没有 关联的表 (注意是没有关联) , 我要在查询的 时候 对这些表都查,得到查询结果。 比如 用户 输入了 一串 字符, 我无法判断 他是 想 搜索 信托,保险,银行理财等(这些都对应数据库的表...
  • $res = PhotoModel::find(2); dd($res);//模型对象
  • 数据库建立索引怎么利用索引查询

    千次阅读 2019-03-05 11:32:04
    数据库建立索引怎么利用索引查询?精选 1.合理使用索引 索引是数据库中重要的数据结构,它的根本目的就是为了提高查询效率。现在大多数的数据库产品都采用IBM最先提出的ISAM索引结构。 索引的使用要恰到好处,其...

    数据库建立索引怎么利用索引查询? 精选

    1.合理使用索引
    索引是数据库中重要的数据结构,它的根本目的就是为了提高查询效率。现在大多数的数据库产品都采用IBM最先提出的ISAM索引结构。
    索引的使用要恰到好处,其使用原则如下:
    在经常进行连接,但是没有指定为外键的列上建立索引,而不经常连接的字段则由优化器自动生成索引。
    在频繁进行排序或分组(即进行group by或order by操作)的列上建立索引。
    在条件表达式中经常用到的不同值较多的列上建立检索,在不同值少的列上不要建立索引。比如在雇员表的“性别”列上只有“男”与“女”两个不同值,因此就无必要建立索引。如果建立索引不但不会提高查询效率,反而会严重降低更新速度。
    如果待排序的列有多个,可以在这些列上建立复合索引(compound index)。
    使用系统工具。如Informix数据库有一个tbcheck工具,可以在可疑的索引上进行检查。在一些数据库服务器上,索引可能失效或者因为频繁操作而 使得读取效率降低,如果一个使用索引的查询不明不白地慢下来,可以试着用tbcheck工具检查索引的完整性,必要时进行修复。另外,当数据库表更新大量 数据后,删除并重建索引可以提高查询速度。
    (1)在下面两条select语句中:
    SELECT * FROM table1 WHERE field1<=10000 AND field1>=0;
    SELECT * FROM table1 WHERE field1>=0 AND field1<=10000;
    如果数据表中的数据field1都>=0,则第一条select语句要比第二条select语句效率高的多,因为第二条select语句的第一个条件耗费了大量的系统资源。
    第一个原则:在where子句中应把最具限制性的条件放在最前面。
    (2)在下面的select语句中:
    SELECT * FROM tab WHERE a=… AND b=… AND c=…;
    若有索引index(a,b,c),则where子句中字段的顺序应和索引中字段顺序一致。
    第二个原则:where子句中字段的顺序应和索引中字段顺序一致。
    ——————————————————————————
    以下假设在field1上有唯一索引I1,在field2上有非唯一索引I2。
    ——————————————————————————
    (3) SELECT field3,field4 FROM tb WHERE field1='sdf' 快
    SELECT * FROM tb WHERE field1='sdf' 慢[/cci]
    因为后者在索引扫描后要多一步ROWID表访问。
    (4) SELECT field3,field4 FROM tb WHERE field1>='sdf' 快
    SELECT field3,field4 FROM tb WHERE field1>'sdf' 慢
    因为前者可以迅速定位索引。
    (5) SELECT field3,field4 FROM tb WHERE field2 LIKE 'R%' 快
    SELECT field3,field4 FROM tb WHERE field2 LIKE '%R' 慢,
    因为后者不使用索引。
    (6) 使用函数如:
    SELECT field3,field4 FROM tb WHERE upper(field2)='RMN'不使用索引。
    如果一个表有两万条记录,建议不使用函数;如果一个表有五万条以上记录,严格禁止使用函数!两万条记录以下没有限制。
    (7) 空值不在索引中存储,所以
    SELECT field3,field4 FROM tb WHERE field2 IS[NOT] NULL不使用索引。
    (8) 不等式如
    SELECT field3,field4 FROM tb WHERE field2!='TOM'不使用索引。
    相似地,
    SELECT field3,field4 FROM tb WHERE field2 NOT IN('M','P')不使用索引。
    (9) 多列索引,只有当查询中索引首列被用于条件时,索引才能被使用。
    (10) MAX,MIN等函数,使用索引。
    SELECT max(field2) FROM tb 所以,如果需要对字段取max,min,sum等,应该加索引。
    一次只使用一个聚集函数,如:
    SELECT “min”=min(field1), “max”=max(field1) FROM tb
    不如:SELECT “min”=(SELECT min(field1) FROM tb) , “max”=(SELECT max(field1) FROM tb)
    (11) 重复值过多的索引不会被查询优化器使用。而且因为建了索引,修改该字段值时还要修改索引,所以更新该字段的操作比没有索引更慢。
    (12) 索引值过大(如在一个char(40)的字段上建索引),会造成大量的I/O开销(甚至会超过表扫描的I/O开销)。因此,尽量使用整数索引。 Sp_estspace可以计算表和索引的开销。
    (13) 对于多列索引,ORDER BY的顺序必须和索引的字段顺序一致。
    (14) 在sybase中,如果ORDER BY的字段组成一个簇索引,那么无须做ORDER BY。记录的排列顺序是与簇索引一致的。
    (15) 多表联结(具体查询方案需要通过测试得到)
    where子句中限定条件尽量使用相关联的字段,且尽量把相关联的字段放在前面。
    SELECT a.field1,b.field2 FROM a,b WHERE a.field3=b.field3
    field3上没有索引的情况下:
    对a作全表扫描,结果排序
    对b作全表扫描,结果排序
    结果合并。
    对于很小的表或巨大的表比较合适。
    field3上有索引
    按照表联结的次序,b为驱动表,a为被驱动表
    对b作全表扫描
    对a作索引范围扫描
    如果匹配,通过a的rowid访问
    (16) 避免一对多的join。如:
    SELECT tb1.field3,tb1.field4,tb2.field2 FROM tb1,tb2 WHERE tb1.field2=tb2.field2 AND tb1.field2=‘BU1032’ AND tb2.field2= ‘aaa’
    不如:
    declare @a varchar(80)
    SELECT @a=field2 FROM tb2 WHERE field2=‘aaa’
    SELECT tb1.field3,tb1.field4,@a FROM tb1 WHERE field2= ‘aaa’
    (16) 子查询
    用exists/not exists代替in/not in操作
    比较:
    SELECT a.field1 FROM a WHERE a.field2 IN(SELECT b.field1 FROM b WHERE b.field2=100)
    SELECT a.field1 FROM a WHERE EXISTS( SELECT 1 FROM b WHERE a.field2=b.field1 AND b.field2=100)
    SELECT field1 FROM a WHERE field1 NOT IN( SELECT field2 FROM b)
    SELECT field1 FROM a WHERE NOT EXISTS( SELECT 1 FROM b WHERE b.field2=a.field1)
    (17) 主、外键主要用于数据约束,sybase中创建主键时会自动创建索引,外键与索引无关,提高性能必须再建索引。
    (18) char类型的字段不建索引比int类型的字段不建索引更糟糕。建索引后性能只稍差一点。
    (19) 使用count(*)而不要使用count(column_name),避免使用count(DISTINCT column_name)。
    (20) 等号右边尽量不要使用字段名,如:
    SELECT * FROM tb WHERE field1 = field3
    (21) 避免使用or条件,因为or不使用索引。
    2.避免使用order by和group by字句。
    因为使用这两个子句会占用大量的临时空间(tempspace),如果一定要使用,可用视图、人工生成临时表的方法来代替。
    如果必须使用,先检查memory、tempdb的大小。
    测试证明,特别要避免一个查询里既使用join又使用group by,速度会非常慢!
    3.尽量少用子查询,特别是相关子查询。因为这样会导致效率下降。
    一个列的标签同时在主查询和where子句中的查询中出现,那么很可能当主查询中的列值改变之后,子查询必须重新查询一次。查询嵌套层次越多,效率越低,因此应当尽量避免子查询。如果子查询不可避免,那么要在子查询中过滤掉尽可能多的行。
    4.消除对大型表行数据的顺序存取
    在 嵌套查询中,对表的顺序存取对查询效率可能产生致命的影响。
    比如采用顺序存取策略,一个嵌套3层的查询,如果每层都查询1000行,那么这个查询就要查询 10亿行数据。
    避免这种情况的主要方法就是对连接的列进行索引。
    例如,两个表:学生表(学号、姓名、年龄……)和选课表(学号、课程号、成绩)。如果两个 表要做连接,就要在“学号”这个连接字段上建立索引。
    还可以使用并集来避免顺序存取。尽管在所有的检查列上都有索引,但某些形式的where子句强迫优化器使用顺序存取。
    下面的查询将强迫对orders表执行顺序操作:
    SELECT * FROM orders WHERE (customer_num=104 AND order_num>1001) OR order_num=1008
    虽然在customer_num和order_num上建有索引,但是在上面的语句中优化器还是使用顺序存取路径扫描整个表。因为这个语句要检索的是分离的行的集合,所以应该改为如下语句:
    SELECT * FROM orders WHERE customer_num=104 AND order_num>1001
    UNION
    SELECT * FROM orders WHERE order_num=1008
    这样就能利用索引路径处理查询。
    5.避免困难的正规表达式
    MATCHES和LIKE关键字支持通配符匹配,技术上叫正规表达式。但这种匹配特别耗费时间。例如:SELECT * FROM customer WHERE zipcode LIKE “98_ _ _”
    即使在zipcode字段上建立了索引,在这种情况下也还是采用顺序扫描的方式。如果把语句改为SELECT * FROM customer WHERE zipcode >“98000”,在执行查询时就会利用索引来查询,显然会大大提高速度。
    另外,还要避免非开始的子串。例如语句:SELECT * FROM customer WHERE zipcode[2,3] >“80”,在where子句中采用了非开始子串,因而这个语句也不会使用索引。
    6.使用临时表加速查询
    把表的一个子集进行排序并创建临时表,有时能加速查询。它有助于避免多重排序操作,而且在其他方面还能简化优化器的工作。例如:
    SELECT cust.name,rcvbles.balance,……other COLUMNS
    FROM cust,rcvbles
    WHERE cust.customer_id = rcvlbes.customer_id
    AND rcvblls.balance>0
    AND cust.postcode>“98000”
    ORDER BY cust.name
    如果这个查询要被执行多次而不止一次,可以把所有未付款的客户找出来放在一个临时文件中,并按客户的名字进行排序:
    SELECT cust.name,rcvbles.balance,……other COLUMNS
    FROM cust,rcvbles
    WHERE cust.customer_id = rcvlbes.customer_id
    AND rcvblls.balance>;0
    ORDER BY cust.name
    INTO TEMP cust_with_balance
    然后以下面的方式在临时表中查询:
    SELECT * FROM cust_with_balance
    WHERE postcode>“98000”
    临时表中的行要比主表中的行少,而且物理顺序就是所要求的顺序,减少了磁盘I/O,所以查询工作量可以得到大幅减少。
    注意:临时表创建后不会反映主表的修改。在主表中数据频繁修改的情况下,注意不要丢失数据。
    7.用排序来取代非顺序存取
    非顺序磁盘存取是最慢的操作,表现在磁盘存取臂的来回移动。SQL语句隐藏了这一情况,使得我们在写应用程序时很容易写出要求存取大量非顺序页的查询。

    展开全文
  • 通过建立索引优化MySQL查询速度

    千次阅读 2017-01-19 10:59:31
    因此,提升数据库查询速度迫在眉睫,下面我们来看下如何通过建立索引提升MySQL的查询速度。一,什么是索引 索引是用来快速地寻找那些具有特定值的记录,所有MySQL索引都以B-树的形式保存。如果没有索引,执行查询时...

    公司使用的业务数据库是MySQL,随着公司业务的发展,某些表中的数据变得越来越大,当单表数据量超过几十万后,查询速度明显变慢,导致用户体验下降。因此,提升数据库查询速度迫在眉睫,下面我们来看下如何通过建立索引提升MySQL的查询速度。

    一,什么是索引
    索引是用来快速地寻找那些具有特定值的记录,所有MySQL索引都以B-树的形式保存。如果没有索引,执行查询时MySQL必须从第一个记录开始扫描整个表的所有记录,直至找到符合要求的记录。表里面的记录数量越多,这个操作的代价就越高。如果作为搜索条件的列上已经创建了索引,MySQL无需扫描任何记录即可迅速得到目标记录所在的位置。如果表有1000个记录,通过索引查找记录至少要比顺序扫描记录快100倍。

    假设我们创建了一个名为user的表:

    CREATE TABLE user ( id CHAR(36)NOT NULL, name CHAR(50) NOT NULL );
    

    然后,我们完全随机把1000个不同name值插入到people表。在数据文件中name列没有任何明确的次序。如果我们创建了name列的索引,MySQL将在索引中排序name列,对于索引中的每一项,MySQL在内部为它保存一个数据文件中实际记录所在位置的“指针”。因此,如果我们要查找name等于“shiyong”记录的id(SQL命令为“SELECT id FROM user WHERE name=‘shiyong’;”),MySQL能够在name的索引中查找“shiyong”值,然后直接转到数据文件中相应的行,准确地返回该行的id。在这个过程中,MySQL只需处理一个行就可以返回结果。如果没有“name”列的索引,MySQL要扫描数据文件中的所有记录,即1000个记录!显然,需要MySQL处理的记录数量越少,则它完成任务的速度就越快。

    二,如何创建索引
    创建索引是很简单的,但是如何创建一个需要的索引,这是需要思考的,索引建的好,可以很好的提升查询速度,索引建的不好,不仅提升不了查询速度,还会影响数据的新增修改速度。

    在性能优化过程中,选择在哪些列上创建索引是最重要的步骤之一。可以考虑使用索引的主要有两种类型的列:在WHERE子句中出现的列,在join子句中出现的列。请看下面这个查询:

    SELECT age ## 不使用索引

    FROM people WHERE firstname=‘Mike’ ## 考虑使用索引

    AND lastname=‘Sullivan’ ## 考虑使用索引

    这个查询与前面的查询略有不同,但仍属于简单查询。由于age是在SELECT部分被引用,MySQL不会用它来限制列选择操作。因此,对于这个查询来说,创建age列的索引没有什么必要。下面是一个更复杂的例子:

    SELECT people.age, ##不使用索引

    town.name ##不使用索引

    FROM people LEFT JOIN town ON

    people.townid=town.townid ##考虑使用索引

    WHERE firstname=‘Mike’ ##考虑使用索引

    AND lastname=‘Sullivan’ ##考虑使用索引

    与前面的例子一样,由于firstname和lastname出现在WHERE子句中,因此这两个列仍旧有创建索引的必要。除此之外,由于town表的townid列出现在join子句中,因此我们需要考虑创建该列的索引。那么,我们是否可以简单地认为应该索引WHERE子句和join子句中出现的每一个列呢?差不多如此,但并不完全。我们还必须考虑到对列进行比较的操作符类型。MySQL只有对以下操作符才使用索引:<,<=,=,>,>=,BETWEEN,IN,以及某些时候的LIKE。可以在LIKE操作中使用索引的情形是指另一个操作数不是以通配符(%或者_)开头的情形。例如,“SELECT peopleid FROM people WHERE firstname LIKE ‘Mich%’;”这个查询将使用索引,但“SELECT peopleid FROM people WHERE firstname LIKE ‘%ike’;”这个查询不会使用索引。

    三,创建组合索引
    索引可以是单列索引,也可以是多列索引。下面我们通过具体的例子来说明这两种索引的区别。假设有这样一个people表:

    CREATE TABLE people ( peopleid 
     
    SMALLINT NOT NULL AUTO_INCREMENT,
     
    firstname CHAR(50) NOT NULL, lastname CHAR(50) NOT NULL, 
     
    age SMALLINT NOT NULL,
     
    townid SMALLINT NOT NULL, PRIMARY KEY (peopleid) );
    

    下面是我们插入到这个people表的数据:

    这个数据片段中有四个名字为“Mikes”的人(其中两个姓Sullivans,两个姓McConnells),有两个年龄为17岁的人,还有一个名字与众不同的Joe Smith。

    这个表的主要用途是根据指定的用户姓、名以及年龄返回相应的peopleid。例如,我们可能需要查找姓名为Mike Sullivan、年龄17岁用户的peopleid(SQL命令为SELECT peopleid FROM people WHERE firstname=‘Mike’ AND lastname=‘Sullivan’ AND age=17;)。由于我们不想让MySQL每次执行查询就去扫描整个表,这里需要考虑运用索引。

    首先,我们可以考虑在单个列上创建索引,比如firstname、lastname或者age列。如果我们创建firstname列的索引(ALTER TABLE people ADD INDEX firstname (firstname);),MySQL将通过这个索引迅速把搜索范围限制到那些firstname='Mike’的记录,然后再在这个“中间结果集”上进行其他条件的搜索:它首先排除那些lastname不等于“Sullivan”的记录,然后排除那些age不等于17的记录。当记录满足所有搜索条件之后,MySQL就返回最终的搜索结果。

    由于建立了firstname列的索引,与执行表的完全扫描相比,MySQL的效率提高了很多,但我们要求MySQL扫描的记录数量仍旧远远超过了实际所需要的。虽然我们可以删除firstname列上的索引,再创建lastname或者age列的索引,但总地看来,不论在哪个列上创建索引搜索效率仍旧相似。

    为了提高搜索效率,我们需要考虑运用多列索引。如果为firstname、lastname和age这三个列创建一个多列索引,MySQL只需一次检索就能够找出正确的结果!下面是创建这个多列索引的SQL命令:

    ALTER TABLE people ADD INDEX fname_lname_age (firstname,lastname,age); 
    

    由于索引文件以B-树格式保存,MySQL能够立即转到合适的firstname,然后再转到合适的lastname,最后转到合适的age。在没有扫描数据文件任何一个记录的情况下,MySQL就正确地找出了搜索的目标记录!

    那么,如果在firstname、lastname、age这三个列上分别创建单列索引,效果是否和创建一个firstname、lastname、age的多列索引一样呢?答案是否定的,两者完全不同。当我们执行查询的时候,MySQL只能使用一个索引。如果你有三个单列的索引,MySQL会试图选择一个限制最严格的索引。但是,即使是限制最严格的单列索引,它的限制能力也肯定远远低于firstname、lastname、age这三个列上的多列索引。

    多列索引还有另外一个优点,它通过称为最左前缀(Leftmost Prefixing)的概念体现出来。继续考虑前面的例子,现在我们有一个firstname、lastname、age列上的多列索引,我们称这个索引为fname_lname_age。当搜索条件是以下各种列的组合时,MySQL将使用fname_lname_age索引:

    firstname,lastname,age

    firstname,lastname

    firstname

    从另一方面理解,它相当于我们创建了(firstname,lastname,age)、(firstname,lastname)以及(firstname)这些列组合上的索引。下面这些查询都能够使用这个fname_lname_age索引:

    SELECT peopleid FROM people 
     
    WHERE firstname='Mike' AND lastname='Sullivan' AND age='17'; 
     
    SELECT peopleid FROM people WHERE firstname='Mike' AND lastname='Sullivan'; 
     
    SELECT peopleid FROM people WHERE firstname='Mike'; 
     
    The following queries cannot use the index at all: 
     
    SELECT peopleid FROM people WHERE lastname='Sullivan'; 
     
    SELECT peopleid FROM people WHERE age='17'; 
     
    SELECT peopleid FROM people WHERE lastname='Sullivan' AND age='17';
    

    四,使用索引的注意事项
    1.索引不会包含有NULL值的列

    只要列中包含有NULL值都将不会被包含在索引中,复合索引中只要有一列含有NULL值,那么这一列对于此复合索引就是无效的。所以我们在数据库设计时不要让字段的默认值为NULL。

    2.使用短索引

    对串列进行索引,如果可能应该指定一个前缀长度。例如,如果有一个CHAR(255)的列,如果在前10个或20个字符内,多数值是惟一的,那么就不要对整个列进行索引。短索引不仅可以提高查询速度而且可以节省磁盘空间和I/O操作。

    3.索引列排序

    MySQL查询只使用一个索引,因此如果where子句中已经使用了索引的话,那么order by中的列是不会使用索引的。因此数据库默认排序可以符合要求的情况下不要使用排序操作;尽量不要包含多个列的排序,如果需要最好给这些列创建复合索引。

    4.like语句操作

    一般情况下不鼓励使用like操作,如果非使用不可,如何使用也是一个问题。like “%aaa%” 不会使用索引而like “aaa%”可以使用索引。

    5.不要在列上进行运算

    select * from users where YEAR(adddate)<2007;
    

    将在每个行上进行运算,这将导致索引失效而进行全表扫描,因此我们可以改成:

    select * from users where adddate<‘2007-01-01'; 
    

    6.不使用NOT IN和<>操作

    五,总结
    索引可以提高查询速度,但过多的使用索引将会造成滥用。因此索引也会有它的缺点:
    1.虽然索引大大提高了查询速度,同时却会降低更新表的速度,如对表进行INSERT、UPDATE和DELETE。因为更新表时,MySQL不仅要保存数据,还要保存一下索引文件。

    2.建立索引会占用磁盘空间的索引文件。一般情况这个问题不太严重,但如果你在一个大表上创建了多种组合索引,索引文件的会膨胀很快。

    索引只是提高效率的一个因素,如果你的MySQL有大数据量的表,就需要花时间研究建立最优秀的索引,或优化查询语句。

    展开全文
  • 1、左侧列表中右键单击数据库,新建数据库,输入你希望的数据库名称,这里我建立了一个名为MyTest的数据库。 2、点击新建查询 (注意:左上角的框里是你之前建立的数据库的名称,不要不小心弄成了master中的查询...

    SQL Sever如何建立数据库,建立表,插入数据并进行查询语句操作

    1、在左侧列表中右键单击数据库,新建数据库,输入你希望的数据库名称,在这里我建立了一个名为MyTest的数据库。
    在这里插入图片描述
    2、点击新建查询
    (注意:左上角的框里是你之前建立的数据库的名称,不要不小心弄成了master中的查询)
    在这里插入图片描述
    比如要建立一个Student表
    (注意:为什么有红线,是因为我已经建立了Student表,为了演示再次输入了一次,所以第一次建表的时候不会出现这种问题。)
    —————————————————————————————————
    注:如果出现已经建了表,查询时出现对象无效,出现下划线的问题。
    可以尝试 编辑-------> IntelliSense ------->刷新本地缓存
    解决。
    在这里插入图片描述
    依次建立了三个表左侧刷新就可以看到建立的三个表。在这里插入图片描述
    3、插入数据。
    在MyTest的查询中,用INSERT INTO 语句插入数据。
    在这里插入图片描述
    需要输入多少行数据取决于表的需求。
    4、表建立好了,数据也有了,就可以进行数据查询的操作。例如:
    在这里插入图片描述
    在这里插入图片描述
    至此建表并插入数据就完成了

    展开全文
  • 索引的优势当然是提高检索速度,但并不是说数据库建立了索引就真的会提高检索速度.为什么呢?我们知道,索引本身是有序的,索引查找的时候一般是多分查找,(当然内存用数组实现的索引则可以做到随机查找,但数据库一般很...
  • 插入查询用户以及建立关系

    千次阅读 2017-08-18 10:56:40
    序言:本节接着上一章简单的介绍之后,继续学习Neo4j这门语言文笔不好尽量用简单的语言来让读者易读易懂,本文的内容都是我学习的过程中一点点积累的. 1.新建一个数据库,添加用户. 2.为数据库中的用户建立简单的...
  • 建立临时表再查询 with AAA(ENODEB_ID,EARFCN)as ( select distinct A.ENODEB_ID,A.EARFCN from tbcell as A, tbCell as B where A.ENODEB_ID=B.ENODEB_ID and (A.longitudeor A.latitudeand A.EARFCN=B....
  • sqlite建立inner join 查询

    千次阅读 2010-07-13 10:34:00
    table 1 bookbrief,price,type_id,author,book_name,idtable 2 booktypedetail,title,type_id查询book表中的所有字段和booktype表中的title中的信息用到inner join注意:是表与一个查询inner join,也是就说inner ...
  • 多个条件的查询建立索引

    千次阅读 2017-01-19 09:57:26
    3、经常与其他表进行连接的表,连接字段上应该建立索引; 4、经常出现Where子句中的字段,特别是大表的字段,应该建立索引; 5、索引应该建选择性高的字段上; 6、索引应该建小字段上,对于大的文本字段...
  • 9.3.原生查询 EJB QL中富有大量的查询...原生查询能反回实体,栏位值,或者两者的组合.EntityManager接口有三种方法来建立原生查询:一种返回标量值,一种是返回实体类型,最后一种是定义一个复杂的结果集,它能映射到多个
  • 如果我们对某一字段增加索引,查询时就会先去索引列表中一次定位到特定值的行数,大大减少遍历匹配的行数,所以能明显增加查询的速度。 添加索引的话,首先去索引列表中查询,而我们的索引列表是B类树的数据结构,...
  • 大家好,我现在想做历史查询,把历史的记录保存然后做历史查询,要建立一个历史变,然后在原表上加入触发器,请问触发器语句怎么写,我是要将原表的所有字段,不管是修改还是没修改的的记录都存入历史变,因为要做...
  • sybase 建立索引 后查询仍旧很慢

    千次阅读 2013-10-11 18:59:49
    最近发现sybase中建立了一个表放了100w条数据查询很慢,之前已经建立了索引,且也分配了高速缓存给它,也将tempdb分离了出来,但是还是很慢。 网上说sybase索引有时候不会自我更新,于是,我抱着试试看的态度将...
  • mysql 建立多个索引,加快查询速度

    千次阅读 2016-08-03 10:45:08
    最近有一个接口,客户端接到...mysql里用sql查询了一下,发现是0.64s,请龙哥帮忙看了一下,他的建议是建立多个索引,加快查询速度。 案例1: 一. 获取查询情况 explain sql语句龙哥,发现没有索引 二.查
  • SQL 如何建立索引来加快数据库的查询

    千次阅读 多人点赞 2020-04-02 18:35:25
    文章目录1. 什么是索引2. 索引的特点3. 索引的分类3.1. 普通索引3.2. 唯一索引(unique)3.3. 主键索引(primary key)3.4. 单列索引3.5. 组合索引3.6.... 创建表创建索引5.2.2. 已经存在的表上...
  • 情况描述:MySQL的user表中,对a,b,c三个字段建立联合索引,那么查询时使用其中的2个作为查询条件,是否还会走索引? 根据查询字段的位置不同来决定,如查询a, a,b a,b,c a,c 都可以走索引的,其他条件的查询不...
  • 在查询语句前添加 USE 库名 SELECT …
  • sql将查询结果建立为新表

    万次阅读 2013-12-31 18:09:42
    fields和lines前面,(col_name_or_user_var,…)后面 如果你使用的时候直接把要写的这些属性放在表名后面,这样是不正确的,一定要写到fields和lines的后面! 网友回复:引用 5 楼 wufongming 的回复: MySQL不...
  • 查询两个有关联的数据表,一个表是cate分类表,另一个是game游戏表, 分类表的id=game表的cate_id ,不用表连接,不建立外键,怎么将game表的数据和cate表的数据一一对应查出来。 求答
  • 我的上一篇博客Explain 检测SQL语句的性能>>中简单的介绍了explain关键字查询结果字段.这篇博客将介绍如何用正确使用索引提高查询效率.  索引用于快速找出某个列中有一特定值的行。不使用索引,MySQL必须从第1...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 912,788
精华内容 365,115
关键字:

在建立查询时