当前位置: 首页 > 科技观察

MySQL数据库常见索引问题详解:无索引、隐式转换、举例

时间:2023-03-12 02:12:40 科技观察

概述在这些年的工作中,因SQL问题导致的数据库故障层出不穷,而索引问题又是SQL问题中出现频率最高的,常见的索引问题包括:没有索引,隐式转换。索引问题1.没有索引。当数据库中没有索引访问表时,没有索引的SQL会造成全表扫描。如果表数据量大,扫描数据量大,应用请求就会变慢,占用数据库连接,连接积累很快就会达到数据库的最大值。如果设置了连接数,新的申请请求会被拒绝,会出现失败。2.隐式转换隐式转换是指SQL查询条件中传入的值与对应字段的数据定义不一致,导致索引无法使用。常见的隐士转换,比如表结构定义的字段是字符类型,但是SQL输入的值是数字;或字段定义排序规则区分大小写。在多表关联的场景下,表的关联字段区分大小写的定义是不同的。相同的。隐式转换会使索引不可用,然后上面提到的慢SQL积累数据库连接数就会用完。不带索引的表结构示例:执行计划:从上面的SQL中可以看到执行计划中有ALL,也就是说这条SQL执行计划是全表扫描。每次执行需要扫描707250行数据,性能消耗很大。我应该怎么做?优化?添加索引。验证mo字段的可过滤性:可以看到mo字段的可过滤性很高。进一步的验证可以通过选择count(*)asall_count,count(distinctmo)asdistinct_cntfromuser来做,比较all_count和distinct_cnt的值进行比较,如果all_cnt和distinct_cnt相差很大,加一个非常有效mo字段上的索引。添加索引mysql>altertableuseraddindexind_mo(mo);mysql>SELECTuidFROM`user`WHEREmo=13772556391LIMIT0,1;执行计划:隐式转换表结构:执行计划:mysql>explainextendedselectuidfrom`user`wheremo=13772556391limit0,1;mysql>showwarnings;Warning1:不能使用index'ind_mo'duetotypeorcollat??ionconversiononfield'mo'注:select`user`.`uid`AS`uid`from`user`where(`user`.`mo`=13772556391)limit0,1如何解决:在上面的情况下,由于表结构在mo字段后定义了string数据类型,但是应用传入了一个数字,导致隐式转换,无法使用索引,所以解决方案有两种:一是修改表结构mo到数字数据类型。第二,修改应用程序,将应用程序中传递的字符类型更改为数据类型。小结在使用索引的时候,我们可以通过explain+extended查看SQL的执行计划,判断是否使用了索引,是否发生了隐式转换。由于常见的隐式转换是由于字段数据类型和排序规则定义不当造成的,因此在设计和开发阶段应避免数据库字段定义和隐式转换。