草庐IT

MySQL技术专题(12)多表优化及避免索引失效

洛神灬殇 2023-08-21 原文

左连接:

** select * from teacher t left outer join course2 c on t.cid = c.cid where cname ='java'**

索引往哪张表加?

-- 小表驱动大表

where 小表.x = 大表.y

ex: ****小表:10 大表:300

双层循环

image

当编写 on t.cid = c.cid 语句时 将数据量小的表放左边

索引建立在经常使用的字段

** 一般情况 左外连接 给左表加索引 右外连接 给右表加索引 **

三表优化

a.小表驱动大表

b.索引建立在经常查询的字段上

避免索引失效的一些原则

a.复合索引,不要跨列或无序使用 最佳左前缀

b复合索引.尽量使用全索引匹配

c.不要在索引上进行任何操作(计算,函数,类型转换)否则索引失效

image

** 对于复合索引,如果左边失效,右侧全部失效 假设有一索引(a,b,c) 例如 b失效,则b,c也失效****复合索引不能使用不等于 (!= <>)或is null 或 is not null 否则自身以及右侧所有全部失效**

** sql优化 是一种概率层面的优化 至于是否实际使用了我们的优化 要通过 explain 来进行推测**

体验概率情况(< > =): 原因是服务层中有sql优化器,可能会影响我们的优化

-- 复合索引中如果有> 则自身和右侧索引全部失效

一般而言,范围查询(> < in )之后的索引都会失效

image

建议:尽量使用索引覆盖 using index

like尽量以“常量开头” 不要以‘%’开头 否则索引失效

image
image
image

一些其他的优化方法

优化exist 和 in

select .. from talbe where exist/in 子查询

如果子查询的数据集大,则使用in

如果子查询的数据集大,则使用exist

exist语法:将主查询的结果,放到子查询中进行条件校验‘子查询是否有数据,如果有数据 则校验成功 如果复合校验则保留数据

order by 优化

有两种算法: 双路排序 单路排序

依据:根据IO的次数

MySQL 4.1之前 默认使用双路排序 :双路:扫描2次磁盘

1.从磁盘读取排序字段,对排序字段进行排序 在buffer中进行的排序

2.扫描其他字段

image

缺陷: IO比较消耗性能

4.1之后,默认使用单路排序

1. 只读取一次 全部字段

在buffer中进行排序 但此种单路排序 会有一定的隐患

不定真的是 “单路|1次IO” 有可能多次IO

原因: 如果数据量特别大,则无法将所有字段的数据 一次性读取完毕 因此会进行“分片读取 多次读取”

表最终以文件形式保存在磁盘中、从磁盘读取

单路排序比双路排序 会占用更多的buffer

单路排序在使用时,如果数据大,可以考虑调大bufferr 的容量大小

set max_length_for_sort_data = 2048 单位byte

如果max_length_for_sort_data值太低 则mysql会自动从 单路-》双路

太低指的是需要排序的列的总大小超过了max_length_for_sort_data定义的字节数

提高order by 查询的策略

a.选择使用单路,双路:调整buffer容量大小

b.避免select * ....

c.复合索引 不要跨列使用 避免using filesort

d.尽量保证全部的排序字段 排序的一致性 都是升序 或降序

有关MySQL技术专题(12)多表优化及避免索引失效的更多相关文章

  1. ruby-on-rails - RSpec:避免使用允许接收的任何实例 - 2

    我正在处理旧代码的一部分。beforedoallow_any_instance_of(SportRateManager).toreceive(:create).and_return(true)endRubocop错误如下:Avoidstubbingusing'allow_any_instance_of'我读到了RuboCop::RSpec:AnyInstance我试着像下面那样改变它。由此beforedoallow_any_instance_of(SportRateManager).toreceive(:create).and_return(true)end对此:let(:sport_

  2. Unity 热更新技术 | (三) Lua语言基本介绍及下载安装 - 2

    ?博客主页:https://xiaoy.blog.csdn.net?本文由呆呆敲代码的小Y原创,首发于CSDN??学习专栏推荐:Unity系统学习专栏?游戏制作专栏推荐:游戏制作?Unity实战100例专栏推荐:Unity实战100例教程?欢迎点赞?收藏⭐留言?如有错误敬请指正!?未来很长,值得我们全力奔赴更美好的生活✨------------------❤️分割线❤️-------------------------

  3. 使用canal同步MySQL数据到ES - 2

    文章目录一、概述简介原理模块二、配置Mysql使用版本环境要求1.操作系统2.mysql要求三、配置canal-server离线下载在线下载上传解压修改配置单机配置集群配置分库分表配置1.修改全局配置2.实例配置垂直分库水平分库3.修改group-instance.xml4.启动监听四、配置canal-adapter1修改启动配置2配置映射文件3启动ES数据同步查询所有订阅同步数据同步开关启动4.验证五、配置canal-admin一、概述简介canal是Alibaba旗下的一款开源项目,Java开发。基于数据库增量日志解析,提供增量数据订阅&消费。Git地址:https://github.co

  4. MIMO-OFDM无线通信技术及MATLAB实现(1)无线信道:传播和衰落 - 2

     MIMO技术的优缺点优点通过下面三个增益来总体概括:阵列增益。阵列增益是指由于接收机通过对接收信号的相干合并而活得的平均SNR的提高。在发射机不知道信道信息的情况下,MIMO系统可以获得的阵列增益与接收天线数成正比复用增益。在采用空间复用方案的MIMO系统中,可以获得复用增益,即信道容量成倍增加。信道容量的增加与min(Nt,Nr)成正比分集增益。在采用空间分集方案的MIMO系统中,可以获得分集增益,即可靠性性能的改善。分集增益用独立衰落支路数来描述,即分集指数。在使用了空时编码的MIMO系统中,由于接收天线或发射天线之间的间距较远,可认为它们各自的大尺度衰落是相互独立的,因此分布式MIMO

  5. ruby-on-rails - 协会的 Rails 索引 - 2

    我发现自己需要这个。假设cart是一个包含用户列表的模型。defindex_of_itemcart.users.each_with_indexdo|u,i|ifu==current_userreturniendend获取此类关联索引的更简单方法是什么? 最佳答案 indexArray上的方法与您的index_of_item方法相同,例如cart.users.index(current_user)返回数组中第一个对象的索引==给obj。如果未找到匹配项,则返回nil。 关于ruby-on-

  6. ruby - Rails -- :id attribute? 所需的数据库索引 - 2

    因此,当我遵循MichaelHartl的RubyonRails教程时,我注意到在用户表中,我们为:email属性添加了一个唯一索引,以提高find的效率方法,因此它不会逐行搜索。到目前为止,我们一直在根据情况使用find_by_email和find_by_id进行搜索。然而,我们从未为:id属性设置索引。:id是否自动索引,因为它在默认情况下是唯一的并且本质上是顺序的?或者情况并非如此,我应该为:id搜索添加索引吗? 最佳答案 大多数数据库(包括sqlite,这是RoR中的默认数据库)会自动索引主键,对于RailsMigration

  7. ruby-on-rails - 无法安装 mysql2 0.3.14 gem - 2

    我看到其他人也遇到过类似的问题,但没有一个解决方案对我有用。0.3.14gem与其他gem文件一起存在。我已经完全按照此处指示完成了所有操作:https://github.com/brianmario/mysql2.我仍然得到以下信息。我不知道为什么安装程序指示它找不到include目录,因为我已经检查过它存在。thread.h文件存在,但不在ruby​​目录中。相反,它在这里:C:\RailsInstaller\DevKit\lib\perl5\5.8\msys\CORE\我正在运行Windows7并尝试在Aptana3中构建我的Rails项目。我的Ruby是1.9.3。$gemin

  8. ruby - 如何使用 ruby​​ mysql2 执行事务 - 2

    我已经开始使用mysql2gem。我试图弄清楚一些基本的事情——其中之一是如何明确地执行事务(对于批处理操作,比如多个INSERT/UPDATE查询)。在旧的ruby-mysql中,这是我的方法:client=Mysql.real_connect(...)inserts=["INSERTINTO...","UPDATE..WHEREid=..",#etc]client.autocommit(false)inserts.eachdo|ins|beginclient.query(ins)rescue#handleerrorsorabortentirelyendendclient.commi

  9. ruby - 引用具有指定索引的枚举器值 - 2

    假设我有一个可枚举对象enum,现在我想获取第三个项目。我知道一种通用方法是转换成数组,然后使用索引访问,如:enum.to_a[2]但这种方式会创建一个临时数组,效率可能很低。现在我使用:enum.each_with_index{|v,i|breakvifi==2}但这非常丑陋和多余。执行此操作最有效的方法是什么? 最佳答案 你可以使用take剥离前三个元素,然后剥离last从take给你的数组中获取第三个元素:third=enum.take(3).last如果您根本不想生成任何数组,那么也许:#Ifenumisn'tanEnum

  10. ruby - 将 Logstash 中的时间戳时区转换为输出索引名称 - 2

    在我的场景中,Logstash收到的系统日志行的“时间戳”是UTC,我们在Elasticsearch输出中使用事件“时间戳”:output{elasticsearch{embedded=>falsehost=>localhostport=>9200protocol=>httpcluster=>'elasticsearch'index=>"syslog-%{+YYYY.MM.dd}"}}我的问题是,在UTC午夜,Logstash在外时区(GMT-4=>America/Montreal)结束前将日志发送到不同的索引,并且索引在20小时(晚上8点)之后没有日志,因为“时间戳”是UTC。我们已

随机推荐