最近公司做了一个千万数量级的项目,由于要求性能比较高,每一个相对慢的查询都需要优化,项目经理是一个比较有经验的开发人员,基本上遇到问题都会先自行处理:或自己分析原因或网络寻求帮助。

但是项目平稳运行一个多月后,他突然说有个SQL。怎么也不走索引,索引怎么建都不走,他查找了网络上可以找到的原因,都无法解决,最后找到我这个兼职dba。

我接到问题也是一脸懵逼,MySQL数据库,是一个表连接的SQL,查询条件列有索引,执行计划中显示索引不使用,强制使用索引也无效。多方面研究发现现象是,单表查询索引列判断等于某个字符串的查询可以使用索引,但是和其他表连接就不使用索引,最后判断是排序规则错误。

大部分索引失效原因是索引列被显式计算或隐式类型转换,其中隐式类型转换包括排序规则冲突,所谓排序规则请自行网络了解,最后解决方案是统一列的排序规则。

总结:

问题原因:排序规则主要针对字符串列,创建表时,列不指定默认表的排序规则,表不指定默认库的排序规则,所以如果建表时,列的排序规则没有指定,则使用逻辑上级的排序规则,一般都是在建库时指定排序规则,如utf8mb4_general_ci或MySQL8默认的utf8mb4_0900_ai_ci。

例如CREATE SCHEMA `库名` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;

如果建表时列指定了排序规则,以指定的为准。这种东西一般不会人为指定,多数情况,是在别的项目中复制的表结构,因原库和新库的排序规则不同,原排序规则被带过来了。当表连接时,使用字符串类型的列作为表连接键时,排序规则不同引起隐式转换,导致索引失效。当使用单表查询索引列判断等于某个字符串例如【列名='abc'】时不需要统一排序规则,不会引发隐式转换,无法排查出此问题

解决方案:统一排序规则

项目上线之前执行以下SQL,会查询出指定库下的所有列的排序规则和字符集,一定要统一后,再上线

select table_name,column_name,character_set_name,collation_name
from information_schema.columns where table_schema = '库名' and data_type = 'varchar'

相关信息请查看MySQL官网对排序规则的描述

最新文章

  1. 代码的坏味道(21)——中间人(Middle Man)
  2. React.js常识
  3. Celery 框架学习笔记
  4. Android Studio Problem : failed to find style 'textviewstyle' in current theme 解决方法
  5. C# List集合Group by查询
  6. poj 1028
  7. JS_ECMA基本语法中的几种封装的小函数-1
  8. POJ 3977
  9. Chorme dev tools小技巧
  10. codeviz安装
  11. sql over()---转载
  12. ListView 实现多选/单选
  13. 10个经典的 Java main 方法面试题
  14. Mapper映射语句高阶应用——ResultMap
  15. PropertiesDemo
  16. C# 合并DLL, 合并DLL进入EXE
  17. HDU 5652 India and China Origins
  18. bzoj4010: [HNOI2015]菜肴制作【拓扑排序】
  19. [bzoj1187][HNOI2007]神奇游乐园
  20. 使用VISIO远程服务器上的ORACLE数据库,反向生成数据库实体关系图

热门文章

  1. Python 用DataFrame读 存 excel
  2. Jmeter系列(49)- 详解 HTTP Cookie 管理器
  3. 对java程序员来说时间格式永远让人挠头来看Java Date Time 教程-时间测量
  4. 笔记:CSS基础
  5. Project ACRN documentation
  6. SVG的引入历程
  7. Hive SQL 优化面试题整理
  8. 软件工程第二次作业(Junit和GoogleTest)
  9. C语言如何动态分配二维数组
  10. python os库的使用方法 + 自动化安装第三方库脚本