MySQL索引失效场景,索引优化,索引原理

news/2024/12/21 22:56:26/

文章主要有以下内容:MySQL性能优化、索引优化、索引失效,索引原理、索引分类。

索引是一个用于提高数据库查询速度的数据结构。不必搜索整个数据库,通过使用索引,数据库系统可以直接找到存储在磁盘上的特定行的地址。没有索引,查询大型数据库可能非常缓慢。

一 索引分类

按照字段类型分类,MySQL索引可以分为以下几种:

1. 普通索引:

 这是最基本的索引,没有任何特殊的限制。

   CREATE INDEX idx_name ON table_name(column_name);

2. 唯一索引:

    与普通索引类似,但要求索引列的所有值都是唯一的(不包括NULL值,因为在MySQL中,多个NULL值是被视为相互不同的)。

CREATE UNIQUE INDEX idx_unique_name ON table_name(column_name);

3. 主键索引:

   每个表只能有一个主键索引。

   它要求所有的主键列的值都是唯一的。

   InnoDB存储引擎的表中,数据的物理存储顺序与主键的顺序相同,也即主键索引是聚簇索引。

ALTER TABLE table_name ADD PRIMARY KEY (column_name);

4. 全文索引:

   专门用于全文搜索。

   仅在MyISAM和InnoDB(从MySQL 5.6版本开始)存储引擎的CHAR、VARCHAR和TEXT列上支持。

   允许使用`MATCH AGAINST`语法来执行全文搜索。

CREATE FULLTEXT INDEX idx_fulltext_name ON table_name(column_name);
SELECT * FROM table_name WHERE MATCH(column_name) AGAINST('keyword');

5. 空间索引:

  专门为地理空间数据类型设计,如`GEOMETRY`、`POINT`、`LINESTRING`、`POLYGON`等。

   使用R-Tree算法。

   允许进行空间位置的查询。

CREATE SPATIAL INDEX idx_spatial_name ON table_name(column_name);SELECT * FROM table_name WHERE MBRContains(column_name, GeomFromText('Polygon(...)'));

6. 前缀索引:

   不是整列作为索引,而是使用列值的前缀部分。

   适用于字符串类型的列,尤其是当文本内容很长时。

CREATE INDEX idx_prefix_name ON table_name(column_name(10));  -- 只使用column_name的前10个字符作为索引

二 索引失效场景

索引失效指的是在进行数据库查询时,虽然存在合适的索引,但由于某种原因,查询并没有使用该索引,从而可能导致性能下降。以下是常见的索引失效的例子及代码示例:

1. 使用LIKE操作符并以通配符开头:

SELECT * FROM users WHERE name LIKE '%John';

2. 使用NOT操作符:

  SELECT * FROM users WHERE NOT age = 25;

3. 列与列的计算:

SELECT * FROM users WHERE salary - tax > 5000;

4. 使用函数处理列:

   SELECT * FROM users WHERE MONTH(birthdate) = 5;

5. 隐式类型转换:

  SELECT * FROM users WHERE age = '25'; -- age是整数列

6. 使用OR操作符连接不在同一索引中的列:

   SELECT * FROM users WHERE age = 25 OR name = 'John';

7. 单独查询复合索引的非最左部分:

   -- 假设存在复合索引(age, name)   SELECT * FROM users WHERE name = 'John';

8. 使用JOIN但未索引的列:

  SELECT * FROM users u JOIN orders o ON u.userID = o.clientID; -- 如果clientID未被索引

9. 对列使用不等式操作符:

   SELECT * FROM users WHERE age <> 25;

10. 使用DISTINCT关键字但没有相应的索引:

    SELECT DISTINCT city FROM users;

11. 对已索引列进行算数操作:

    SELECT * FROM products WHERE price * 0.9 > 100;

12. 使用IS NULL和IS NOT NULL但没有对应的索引:

    SELECT * FROM users WHERE address IS NULL;

13. 使用IN操作符的列表过大:

    SELECT * FROM users WHERE age IN (25, 26, 27, ... , 50);

14. 在JOIN操作中连接类型不匹配的列:

 SELECT * FROM users u JOIN details d ON u.id = CAST(d.user_id AS CHAR);

15. 查询范围过大,使得全表扫描更为高效:

    SELECT * FROM users WHERE age > 10;

16. 索引列上使用负操作:

 SELECT * FROM products WHERE NOT price = 100;

17. 复合索引中某一列使用范围查询:

    -- 假设存在复合索引(age, score)    SELECT * FROM users WHERE age > 25 AND score = 100;

18. 使用COALESCE函数:

 SELECT * FROM users WHERE COALESCE(name, 'Unknown') = 'John';

19. 使用UNION操作:

    SELECT name FROM users WHERE age = 25    UNION    SELECT name FROM users WHERE city = 'Paris';

20. 查询不在索引范围内的数据:

    SELECT * FROM users WHERE age = 500; -- 如果数据库中年龄不可能为500

21. 在HAVING子句中使用未被索引的列:

    SELECT age, COUNT(*) FROM users GROUP BY age HAVING COUNT(*) > 5;

22. 查询结果集太大,导致索引回表:

    SELECT * FROM users WHERE age BETWEEN 20 AND 30;

23. 在ORDER BY子句中使用多个未被索引的列:

    SELECT * FROM users ORDER BY age, name;

24. 使用外部参数进行查询:

    SET @name = 'John';    SELECT * FROM users WHERE name = @name;

25. 使用多个JOIN且索引未被优化:

    SELECT * FROM users u JOIN orders o ON u.id = o.user_id JOIN details d ON o.id = d.order_id;

26. 在WHERE子句中使用CASE语句:

    SELECT * FROM users WHERE (CASE WHEN age = 25 THEN 1 ELSE 0 END) = 1;

27. 对JSON类型的数据进行查询:

    SELECT * FROM users WHERE profile->'$.age' = 25;

28. 查询含有较多重复值的列:

    SELECT * FROM users WHERE gender = 'male'; -- 如果90%的用户都是male

29. 使用非确定性函数:

    SELECT * FROM users WHERE birthdate = NOW();

30. 使用存储过程中的动态SQL:

    CALL search_users('John'); -- 如果存储过程内部使用了动态SQL进行查询

http://www.ppmy.cn/news/1124802.html

相关文章

题目 1060: 二级C语言-同因查找

题目描述 求出10至1000之内能同时被2、3、7整除的数&#xff0c;并输出。 每行一个。 这题思路就像行云流水&#xff0c;可以一气呵成。 for循环10到1&#xff0c;000的数&#xff0c;if判断如果同时被2、3、7整除就输出 #include<iostream> using namespace std;//求…

基于R语言分位数回归丨线性回归假设与分位数函数、线性分位数回归 、贝叶斯分位数回归、超越线性分位数回归等

目录 专题一 线性回归假设与分位数函数讲解 专题二 线性分位数回归 【代码实践】 专题三 贝叶斯分位数回归【代码实践】 专题四 超越线性分位数回归&#xff08;一&#xff09;【代码实践】 专题五 超越线性分位数回归&#xff08;二&#xff09;【代码实践】 更多应用 回…

PostgreSql 统一修改date字段为timestamp

在《Powdersigner PostgreSql 同步表结构到pg数据库》中&#xff0c;导入表结构到pg数据后&#xff0c;发下时间对不上了。mysql的datetime转换后pg的变成了date了。 再同步到数据后&#xff0c;就变成日期类型了。 因为表中基本都有创建时间和修改时间&#xff0c;两个相对固…

【算法】算法设计与分析 课程笔记 第二章 递归与分治策略

2.1 递归 直接或间接地调用自身的算法称为递归算法。 用函数自身给出定义的函数称为递归函数。 2.1.1 阶乘 首先得想到一个求阶乘的函数&#xff1a; 这个函数的下面那个式子就用到了调用自身&#xff0c;所以可以用递归来实现&#xff0c;将主问题拆分成若干层的子问题&am…

二进制中1的个数 C++实现

题目&#xff1a; 代码&#xff1a; #include<iostream> using namespace std; const int N100010; int a[N]; int n;int lowbit(int x){return x & -x; }int main(){scanf("%d",&n);for(int i0;i<n;i) scanf("%d",&a[i]);for(int i…

Spring面试题9:Spring的BeanFactory和FactoryBean的区别和联系

该文章专注于面试,面试只要回答关键点即可,不需要对框架有非常深入的回答,如果你想应付面试,是足够了,抓住关键点 面试官:说一说Spring的BeanFactory和FactoryBean的区别和联系 区别:BeanFactory是一个工厂接口,主要负责管理和创建Bean实例。它是Spring提供的最底层的…

Level FHE 的高效实现 兼容 Level FHE 的高级算法

参考文献&#xff1a; [CS05] Choi Y, Swartzlander E E. Parallel prefix adder design with matrix representation[C]//17th IEEE Symposium on Computer Arithmetic (ARITH’05). IEEE, 2005: 90-98.[SV11] Smart N P, Vercauteren F. Fully homomorphic SIMD operations[…

二、ubuntu主机端tftp及nfs服务开发环境安装

一.主机端tftp服务环境安装及配置 检查是否已经安装tftp server $dpkg -s tftpd-hpa#如果提示未安装服务&#xff0c;则执行下面安装指令$sudo apt-get install tftpd-hpa tftp-hpa#tftpd-hpa服务端 tftp-hpa客户端创建tftp启动目录&#xff0c;用于存放内核与设备树文件&a…