`

mysql关于or前后条件的索引问题

阅读更多

        不是说,一条sql语句只能用一个索引么?但如下这样一条sql语句

SELECT * FROM `comment` WHERE `toconuid` = '10' or `tocomuid` = '10'

        其中toconuid列和tocomuid列分别为单列索引,explain后显示两个索引都用了,extra为 Using union(toconuid,tocomuid); Using where

        在这里,可以理解MYSQL把这个语句拆成了两条语句

SELECT * FROM `comment` WHERE `toconuid` = '10'
union
SELECT * FROM `comment` WHERE `tocomuid` = '10' 

一.索引合并优化

        索引合并方法用于通过range扫描搜索行并将结果合成一个。合并会产生并集、交集或者正在进行的扫描的交集的并集。

        在EXPLAIN输出中,该方法表现为type列内的index_merge。在这种情况下,key列包含一列使用的索引,key_len包含这些索引的最长的关键元素。

例如:

SELECT * FROM tbl_name WHERE key_part1 = 10 OR key_part2 = 20;
 
SELECT * FROM tbl_name WHERE (key_part1 = 10 OR key_part2 = 20) AND non_key_part=30;
 
SELECT * FROM t1, t2 WHERE (t1.key1 IN (1,2) OR t1.key2 LIKE 'value%') AND t2.key1=t1.some_col;

SELECT * FROM t1, t2 WHERE t1.key1=1 AND (t2.key1=t1.some_col OR t2.key2=t1.some_col2);

 

二.索引合并方法有几种访问算法 

        参见EXPLAIN输出的Extra字段,有交集、联合、排序并集三种索引合并访问算法。

        注意:索引合并优化算法具有以下几个已知缺陷:

1).如果可以对某些关键字进行范围扫描,则不考虑索引合并。例如,下面的查询:

SELECT * FROM t1 WHERE (goodkey1 < 10 OR goodkey2 < 20) AND badkey < 30;

        对于该查询,可以有两个方案:

        a.使用(goodkey1 < 10 OR goodkey2 < 20)条件进行索引合并扫描。

        b.使用badkey < 30条件进行范围扫描。

        然而,优化器只考虑第2个方案。如果这不是你想要的,你可以通过使用IGNORE INDEX或FORCE INDEX让优化器考虑index_merge。下面的查询使用索引合并执行:

SELECT * FROM t1 FORCE INDEX(goodkey1,goodkey2) WHERE (goodkey1 < 10 OR goodkey2 < 20) AND badkey < 30;
SELECT * FROM t1 IGNORE INDEX(badkey) WHERE (goodkey1 < 10 OR goodkey2 < 20) AND badkey < 30;

2).如果查询有一个复杂的WHERE子句,有较深的AND/OR嵌套关系,MySQL不选择该优选方案,通过下面的识别法则尝试分布各条件:

        a.(x AND y) OR z = (x OR z) AND (y OR z)

        b.(x OR y) AND z = (x AND z) OR (y AND z)

        index_merge访问方法的不同变量之间的选择和其它访问方法基于各适用选项的成本估计。

1.索引合并交集访问算法

        该访问算法可以用于当WHERE子句结合AND被转换为不同的关键字的几个范围条件,每个条件为下面之一:

        以这种形式,即索引有确切的N部分(即包括了所有索引部分):

        a.key_part1=const1 AND key_part2=const2 ... AND key_partN=constN

        b.任何InnoDB或BDB表的主键的范围条件。

        下面是一些例子:

SELECT * FROM innodb_table WHERE primary_key < 10 AND key_col1=20;
SELECT * FROM tbl_name WHERE (key1_part1=1 AND key1_part2=2) AND key2=2;

        索引合并交集算法同时对所有使用的索引进行扫描,并产生从合并的索引扫描接收的行序列的交集。

        如果使用的索引包括查询中使用的所有列,所有表记录均不搜索,并且在这种情况下EXPLAIN的输出包含Extra字段中的Using index。下面是一个此类查询的例子:

SELECT COUNT(*) FROM t1 WHERE key1=1 AND key2=1;

        如果使用的索引未包括查询中使用的所有列,只有满足所有使用的关键字的范围条件才搜索所有记录。

        如果某个合并条件是InnoDB或BDB表的主键的一个条件,不用于记录查询,但用于过滤使用其它条件搜索的记录。

 

2.索引合并并集访问算法

        该算法的适用标准类似于索引合并方法交集算法的标准。算法可以用于当WHERE子句结合OR被转换为不同的关键字的几个范围条件的时候,每个条件为下面之一:

        以这种形式,即索引有确切的N部分(即包括了所有索引部分):

        1).key_part1=const1 AND key_part2=const2 ... AND key_partN=constN

        2).任何InnoDB或BDB表的主键的范围条件。

        3).索引合并方法交集算法适用的一个条件。

        下面是一些例子:

SELECT * FROM t1 WHERE key1=1 OR key2=2 OR key3=3;
 
SELECT * FROM innodb_table WHERE (key1=1 AND key2=2) OR (key3='foo' AND key4='bar') AND key5=5;

 

3.索引合并排序并集访问算法

        该访问算法可以用于当WHERE子句结合OR被转换为不同的关键字的几个范围条件,但索引合并方法联合算法并不适用的时候。

        下面是一些例子:

SELECT * FROM tbl_name WHERE key_col1 < 10 OR key_col2 < 20;

 

文章来源:http://www.educity.cn/wenda/590849.html

分享到:
评论

相关推荐

    mysql关于索引的面试题

    6. **OR操作符**:当OR前后包含非索引列时,即使其他列有索引,整个查询也可能无法使用索引。 最后,提一下数据库和表的字符集选择。在MySQL中,推荐使用`utf8mb4`字符集,因为它支持更广泛的Unicode字符,包括表情...

    Mysql中SQL语句不使用索引的情况

    3. **OR操作符**:如果查询条件中使用了`OR`,且`OR`前后条件中只有前面的列有索引,MySQL将不会使用这些索引。例如,`SELECT * FROM table_name WHERE key1 = 'a' OR key2 = 'b'`,即使`key1`上有索引,查询也不会...

    mysql高频面试题及答案

    - OR条件前后没有同时使用索引的列,或者没有有效的索引覆盖所有条件。 - 不遵循最左前缀原则的组合索引。 - 隐式类型转换导致索引不可用。 - 使用IS NULL或IS NOT NULL。 - 使用NOT、、!=等操作符。 - 函数...

    DTM_mk_MySQL Migration Kit—mysql_wp_oracle2mysql

    - **布尔条件**:AND、OR等。 - **比较条件**:=、!=、&lt;、&gt;等。 - **存在条件**:EXISTS等。 - **范围条件**:BETWEEN等。 - **成员条件**:IN、NOT IN等。 #### 九、附录C:Oracle到MySQL操作符对照 ##### 9.1 ...

    20190727-mysql_sql学习笔记.docx

    - `|`:进行OR匹配,表示匹配其前后两个表达式之一。 - `[和]`:匹配指定范围内的字符,如`[123]`匹配1、2或3。 - `[^123]`:匹配除1、2、3之外的所有字符。 - `-`:定义字符范围,如`[1-9]`匹配1到9的数字。 -...

    MySQL性能优化知识点总结

    - `OR`关键字前后两个条件都需被索引,才能充分发挥索引效能。 2. 优化子查询 子查询可能导致性能下降,因为MySQL需要创建临时表来存储内层查询的结果。若数据量大,这会显著影响速度。解决方法是使用JOIN操作代替...

    数据库mysql+oracle面试题

    4. **避免使用OR连接条件**:使用OR连接条件会使得索引失效,导致全表扫描。可以使用多个独立的查询并使用UNION ALL合并结果来替代。 5. **谨慎使用IN和NOT IN**:在某些情况下,使用IN和NOT IN会导致全表扫描。如果...

    Mysql慢查询优化方法及优化原则

    以下是一些关于如何优化MySQL慢查询的方法和原则: 1. **日期格式与索引**:在进行日期比较时,确保传入的日期格式为'yyyy-MM-dd',这样MySQL能够识别并使用日期类型的索引。例如,将'yyyy'或'yyyy-MM'格式改为'...

    java实现的图书管理售卖系统,有使用mysql数据库和没使用数据库两个版本

    2. 搜索与筛选:用户可以根据书名、作者等关键词进行搜索,还可以通过分类、价格等条件进行筛选。 3. 购物车:用户可以添加书籍到购物车,查看购物车内书籍,修改数量或删除书籍。 4. 订单处理:用户提交订单后,...

    Java 全栈知识点问题汇总(8).pdf

    4. 避免在WHERE子句中使用OR连接条件,考虑使用UNION ALL代替。 5. 使用IN和NOT IN时要谨慎,可能导致全表扫描,连续的数值范围可以用BETWEEN替代IN。 通过理解并实践这些原则,开发者可以更有效地设计和优化数据库...

    Mysql排序和分页(order by&limit)及存在的坑

    MySQL中的排序和分页是数据库查询中非常基础且重要的功能,尤其在处理大量数据时,如电商中的订单查询。本文将详细介绍如何使用`ORDER BY`和`LIMIT`语句进行排序和分页,并讨论其中可能遇到的问题。 首先,排序查询...

    SQL知识点总结.pdf

    字符函数有concat(拼接)、substr(截取子串)、upper(转换为大写)、lower(转换为小写)、trim(去前后空格)、lpad(左填充)、rpad(右填充)、replace(替换)、instr(返回索引)、length(获取长度)等。...

    通用查询组件 简单易用

    这通常包括条件选择器(如下拉菜单、日期选择器等)、输入框以及逻辑运算符(如AND、OR)。 2. **动态构建查询条件**:组件应支持动态生成查询条件,即用户可以在运行时自由添加或移除查询字段,而不仅仅是预设的...

    mybaits动态sql教程

    如果没有where条件满足,它会避免输出整个where语句,而且会智能地忽略开头的and或or。 4. trim:可以在SQL片段的前后添加或覆盖指定的内容。常见的属性有prefix、prefixOverrides(覆盖前面的内容)、suffix和...

    简单的关键字查询

    除了简单的等值匹配,关键字查询还可以扩展到更复杂的条件,如模糊匹配(使用LIKE操作符)、范围查询(使用BETWEEN操作符)和多条件组合(使用AND、OR、NOT操作符)等。 在实际编程中,我们通常会使用某种数据库API...

    Laravel开发-laravel-model-search

    例如,我们可以定义一个`search`Scope,接收一个关键词参数,并在查询时添加`where`或`orWhere`条件,使搜索功能模块化。 ```php public function scopeSearch($query, $keyword) { return $query-&gt;where('name', ...

    2021-2022计算机二级等级考试试题及答案No.2000.docx

    6. **MySQL触发器**:在MySQL中,激活触发器的命令包括`INSERT`、`DELETE`和`UPDATE`,这些命令用于在特定的数据操作前后执行预定义的SQL语句。 7. **输入设备**:输入设备是将外部信息传输到计算机的设备,如键盘...

    sql入门教程

    AND用于指定多个条件都必须满足,而OR用于指定多个条件中至少有一个满足。例如,SELECT store_name FROM Store_Information WHERE sales &gt; 1000 AND date &gt; 'jan-06-1999'。 5. IN、BETWEEN和LIKE关键字:这些条件...

    jqgrid几个实例

    $db = mysql_connect($dbhost, $dbuser, $dbpassword) or die("Connection Error: ".mysql_error()); mysql_select_db($database) or die("Error connecting to db."); // 计算总页数和起始位置 $count = ...; // ...

    2021-2022计算机二级等级考试试题及答案No.3062.docx

    10. 逻辑运算符与条件判断:在表达式中,`AND`和`OR`操作符用于布尔逻辑运算,`NOT`用于取反。例如,表达式`x &gt; 0 AND y`只有在`x`大于0且`y`也大于0时才为真。 11. 数组遍历与索引:在二维数组中,使用循环遍历...

Global site tag (gtag.js) - Google Analytics