<p>SQL 문은 데이터를 조작하고 데이터를 정의할 수 있어 사용자에게 큰 편의성을 제공할 수 있습니다. 이 기사에서는 52가지 SQL 문 성능 최적화 전략에 대해 설명합니다. 도움이 필요한 친구는 수집하는 것이 좋습니다. </p>
<p><img src="https://img.php.cn/upload/article/202103/24/2021032416152970237.jpg" style="max-width:90%" style="max-width:90%" border="0" vspace="0" title="" alt="" style="width: 800px; height: 320px;"></p>
<p><span style="font-size: 18px;"><strong>SQL 문 성능 최적화 전략</strong></span></p>
<p>1. 쿼리를 최적화하려면 먼저 <code>WHERE</code> 및 <code> ORDER BY를 고려해야 합니다. Code>는 관련된 열에 대한 인덱스를 생성합니다. <code>WHERE</code> 及<code> ORDER BY</code> 涉及的列上建立索引。</code></p>
<p>2、应尽量避免在 WHERE 子句中对字段进行 NULL 值判断,创建表时 NULL 是默认值,但大多数时候应该使用<code> NOT NULL</code>,或者使用一个特殊的值,如 <code>0 </code>,<code>-1</code>作为默认值。<br></p>
<p>3、应尽量避免在 WHERE 子句中使用 != 或 <> 操作符。MySQL 只有对以下操作符才使用索引:<code><</code>,<code><=</code>,<code>=</code>,<code>></code>,<code>>=</code>,<code>BETWEEN</code>,<code>IN</code>,以及某些时候的<code> LIKE</code>。<br></p>
<p>4、应尽量避免在 WHERE 子句中使用 OR 来连接条件,否则将导致引擎放弃使用索引而进行全表扫描,可以使用 UNION 合并查询。<br></p>
<p>5、IN 和 NOT IN 也要慎用,否则会导致全表扫描。对于连续的数值,能用 BETWEEN 就不要用 IN。<br></p>
<p>6、下面的查询也将导致全表扫描:</p><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:sql;toolbar:false">select id from t where name like‘%abc%’//用到索引</pre><div class="contentsignin">로그인 후 복사</div></div><p>或者</p><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:sql;toolbar:false">select id from t where name like‘%abc’//若要提高效率,可以考虑全文检索</pre><div class="contentsignin">로그인 후 복사</div></div><p>7、如果在 WHERE 子句中使用参数,也会导致全表扫描。</p><p>8、应尽量避免在 WHERE 子句中对字段进行表达式操作和函数操作。<br/></p><p>9、很多时候用 <code>EXISTS </code>代替 IN 是一个好的选择。<br/></p><p>10、索引固然可以提高相应的 SELECT 的效率,但同时也降低了 <code>INSERT </code>及 <code>UPDATE </code>。因为 INSERT 或 UPDATE 时有可能会重建索引,一个表的索引数最好不要超过 6 个。<br/></p><p>11、应尽可能的避免更新 <code>clustered </code>索引数据列, 因为 clustered 索引数据列的顺序就是表记录的物理存储顺序,一旦该列值改变将导致整个表记录的顺序的调整,会耗费相当大的资源。<br/></p><p>12、尽量使用数字型,若只含数值信息的字段尽量不要设计为字符型,这会降低查询和连接的性能,并会增加存储。<br/></p><p>13、尽可能的使用<code> varchar</code>, <code>nvarchar</code> 代替<code> char</code>, <code>nchar</code>。因为首先长字段存储空间小,可以节省存储空间,对于查询来说,在一个相对较小的字段内搜索效率显然要高些。<br/></p><p>14、最好不要使用返回所有:<code>select from t</code> ,用具体的字段列表代替 “*”,不要返回用不到的任何字段。<br/></p><p>15、尽量避免向客户端返回大数据量,若数据量过大,应该考虑相应需求是否合理。<br/></p><p>16、使用表的别名(Alias):当在 SQL 语句中连接多个表时,请使用表的别名并把别名前缀于每个<code> Column</code> 上。这样一来,就可以减少解析时间并减少那些由 Column 歧义引起的语法错误。<br/></p><p>17、使用“临时表”暂存中间结果 。<br/></p><p>简化 SQL 语句的重要方法就是采用临时表暂存中间结果。将临时结果暂存在临时表,后面的查询就在 <code>tempdb </code>中了,这可以避免程序中多次扫描主表,也大大减少了程序执行中“共享锁”阻塞“更新锁”,减少了阻塞,提高了并发性能。<br/></p><p>18、一些 SQL 查询语句应加上 <code>nolock</code><br/>2. WHERE 절의 필드에 대해 NULL 값 판단을 피하십시오. 테이블을 생성할 때 NULL이 기본값이지만 대부분의 경우 <code> NOT NULL</code>을 사용하거나 특수 문자를 사용해야 합니다. 기본값은 <code>0 </code>, <code>-1</code> 등입니다. </p><p></p>3. WHERE 절에 != 또는 <> 연산자를 사용하지 마세요. MySQL은 다음 연산자에 대해서만 인덱스를 사용합니다: <code><</code>, <code><=</code>, <code>=</code>, <code>></code>, < code>>=</code>, <code>BETWEEN</code>, <code>IN</code>, 때로는 <code>LIKE</code>. <ul style="list-style-type: disc;"><li><p>4. 조건을 연결하기 위해 WHERE 절에 OR을 사용하지 마세요. 그렇지 않으면 엔진이 인덱스 사용을 포기하고 UNION을 사용하여 쿼리를 병합할 수 있습니다. <br/></p></li>5. IN 및 NOT IN도 주의해서 사용해야 합니다. 그렇지 않으면 전체 테이블 스캔으로 이어집니다. 연속형 값의 경우 BETWEEN을 사용할 수 있으면 IN을 사용하지 마세요. <li><p></p>6. 다음 쿼리도 전체 테이블 스캔을 발생시킵니다: </li><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:sql;toolbar:false">select a.personMemberID, * from chineseresume a,personmember b where personMemberID = b.referenceid and a.personMemberID = 'JCNPRH39681' (A = B, B = '号码')
select a.personMemberID, * from chineseresume a,personmember b where a.personMemberID = b.referenceid and a.personMemberID = 'JCNPRH39681' and b.referenceid = 'JCNPRH39681' (A = B, B = '号码', A = '号码')
select a.personMemberID, * from chineseresume a,personmember b where b.referenceid = 'JCNPRH39681' and a.personMemberID = 'JCNPRH39681' (B = '号码', A = '号码')</pre><div class="contentsignin">로그인 후 복사</div></div><div class="contentsignin">로그인 후 복사</div></div><li> 또는 <p><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:sql;toolbar:false">SELECT * FROM record WHERE substrINg(card_no, 1, 4) = '5378' --13秒
SELECT * FROM record WHERE amount/30 < 1000 --11秒
SELECT * FROM record WHERE convert(char(10), date, 112) = '19991201' --10秒</pre><div class="contentsignin">로그인 후 복사</div></div><div class="contentsignin">로그인 후 복사</div></div></p>7. 매개변수가 WHERE 절에 사용되는 경우에도 전체 테이블 스캔이 발생합니다. </li></ul>8. WHERE 절의 필드에서는 표현식 연산과 함수 연산을 피하세요. <p><code>JOIN</code>),考虑使用临时表或表变量存放中间结果。少用子查询,视图嵌套不要过深,一般视图嵌套不要超过 2 个为宜。</p><p>20、将需要查询的结果预先计算好放在表中,查询的时候再<code>Select</code></p>9. IN 대신 <code>EXISTS </code>를 사용하는 것이 좋은 선택인 경우가 많습니다. 🎜🎜🎜10. 인덱스는 해당 SELECT의 효율성을 향상시킬 수 있지만 <code>INSERT </code> 및 <code>UPDATE </code>의 효율성도 감소시킵니다. INSERT 또는 UPDATE 중에 인덱스가 다시 작성될 수 있으므로 테이블에 6개 이상의 인덱스를 포함하지 않는 것이 가장 좋습니다. 🎜🎜🎜11. 클러스터형 인덱스 데이터 열의 순서는 테이블 레코드의 물리적 저장 순서이므로 가능한 한 <code>클러스터형</code> 인덱스 데이터 열을 업데이트하지 않아야 합니다. 전체 테이블 레코드의 조정에는 상당한 리소스가 소모됩니다. 🎜🎜🎜12. 숫자 정보만 포함하는 필드를 문자 유형으로 디자인하지 않으려면 숫자 유형을 사용해 보세요. 이렇게 하면 쿼리 및 연결 성능이 저하되고 저장 공간이 늘어납니다. 🎜🎜🎜13. <code> char</code>, <code>nchar</code> 대신 <code> varchar</code>, <code>nvarchar</code>를 최대한 사용하세요. 우선, 긴 필드는 저장 공간이 작고 저장 공간을 절약할 수 있기 때문에 쿼리의 경우 상대적으로 작은 필드에서 검색하는 것이 분명히 더 효율적입니다. 🎜🎜🎜14 모두 반환을 사용하지 않는 것이 가장 좋습니다. <code>select from t</code>, "*"를 특정 필드 목록으로 바꾸고 사용되지 않는 필드를 반환하지 마세요. 🎜🎜🎜15. 클라이언트에 많은 양의 데이터를 반환하지 않도록 하세요. 데이터 양이 너무 많으면 해당 요구 사항이 합리적인지 고려해야 합니다. 🎜🎜🎜16. 테이블 별칭(Alias) 사용: SQL 문에서 여러 테이블을 연결할 때 테이블 별칭을 사용하고 각 <code> 열</code>에 별칭을 붙입니다. 이렇게 하면 구문 분석 시간이 단축되고 열 모호함으로 인해 발생하는 구문 오류가 줄어듭니다. 🎜🎜🎜17. 중간 결과를 임시로 저장하려면 "임시 테이블"을 사용하세요. 🎜🎜🎜SQL 문을 단순화하는 중요한 방법은 임시 테이블을 사용하여 중간 결과를 임시로 저장하는 것입니다. 임시 결과를 임시 테이블에 임시 저장하면 후속 쿼리는 <code>tempdb</code>에 저장됩니다. 이렇게 하면 프로그램에서 기본 테이블을 여러 번 스캔하는 것을 방지할 수 있으며 "공유 잠금" 차단 및 " 프로그램 실행 중 업데이트 잠금"을 수행하여 차단을 줄이고 동시성 성능을 향상시킵니다. 🎜🎜🎜18. 일부 SQL 쿼리 문에는 <code>nolock</code>을 추가해야 합니다. 동시성 성능을 향상시키기 위해 읽기와 쓰기가 서로 차단됩니다. 일부 쿼리의 경우 읽을 때 쓰기를 허용하는 nolock을 추가할 수 있지만 커밋되지 않은 더티 데이터를 읽을 수 있다는 단점이 있습니다. 🎜🎜🎜nolock 사용에는 세 가지 원칙이 있습니다. 🎜🎜🎜🎜쿼리 결과를 "삽입, 삭제, 수정"에 사용하는 경우 nolock을 추가할 수 없습니다.
🎜🎜🎜🎜쿼리되는 테이블은 페이지 분할이 자주 발생하는 테이블이므로 주의해서 nolock을 사용하세요. 🎜🎜🎜🎜임시 테이블을 사용하면 Oracle의 undo 테이블 공간과 유사한 기능을 가진 "데이터 포섀도우"를 저장할 수도 있습니다. 임시 테이블을 사용하면 향상될 수 있습니다. 동시성 성능을 위해서는 nolock을 사용하지 마세요. 🎜🎜🎜🎜19. 일반적인 단순화 규칙은 다음과 같습니다. 5개 이상의 테이블 연결(<code>JOIN</code>)을 사용하지 말고 임시 테이블이나 테이블 변수를 사용하여 중간 결과를 저장하는 것을 고려하세요. 하위 쿼리를 적게 사용하고 뷰를 너무 깊게 중첩하지 마십시오. 일반적으로 뷰를 2개 이하로 중첩하는 것이 적절합니다. 🎜🎜20. 쿼리할 결과를 미리 계산하여 테이블에 넣은 후 쿼리할 때 <code>선택</code>하세요. 🎜<p>21、用 OR 字句可以分解成多个查询,并且通过 <code>UNION </code>连接多个查询。他们的速度与是否使用索引有关,如果查询需要用到联合索引,用 <code>UNION all </code>执行的效率更高。多个 OR 的字句没有用到索引,改写成 <code>UNION</code> 的形式再试图与索引匹配。<br/></p><p>22、在IN后面值的列表中,将出现最频繁的值放在最前面,出现得最少的放在最后面,减少判断次数。<br/></p><p>23、尽量将数据的处理工作放在服务器上,如使用存储过程。存储过程是编译好、优化过、并且被组织到一个执行规划、且存储在数据库中的 SQL 语句,是控制流语言的集合,速度当然快。反复执行的动态 SQL,可以使用临时存储过程,该过程(临时表)被放在 <code>Tempdb </code>中。</p><p>24、当服务器的内存够多时,<strong>配制线程数量 = 最大连接数+5</strong>,这样能发挥最大的效率;否则使用配制线程数量< 最大连接数,启用 SQL SERVER 的线程池来解决,如果还是数量 = 最大连接数+5,严重的损害服务器的性能。<br/></p><p>25、查询的关联同写的顺序 :<br/></p><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:sql;toolbar:false">select a.personMemberID, * from chineseresume a,personmember b where personMemberID = b.referenceid and a.personMemberID = 'JCNPRH39681' (A = B, B = '号码')
select a.personMemberID, * from chineseresume a,personmember b where a.personMemberID = b.referenceid and a.personMemberID = 'JCNPRH39681' and b.referenceid = 'JCNPRH39681' (A = B, B = '号码', A = '号码')
select a.personMemberID, * from chineseresume a,personmember b where b.referenceid = 'JCNPRH39681' and a.personMemberID = 'JCNPRH39681' (B = '号码', A = '号码')</pre><div class="contentsignin">로그인 후 복사</div></div><div class="contentsignin">로그인 후 복사</div></div><p>26、尽量使用 EXISTS 代替 <code>select count(1)</code> 来判断是否存在记录。count 函数只有在统计表中所有行数时使用,而且 <code>count(1)</code> 比 <code>count(*) </code>更有效率。</p><p>27、尽量使用 “>=”,不要使用 “>”。<br/></p><p>28、索引的使用规范:<br/></p><ul style="list-style-type: disc;"><li><p>索引的创建要与应用结合考虑,建议大的<code> OLTP 表</code>不要超过 6 个索引;<br/>
</p></li><li><p>尽可能的使用索引字段作为查询条件,尤其是聚簇索引,必要时可以通过 <code>index index_name </code>来强制指定索引;</p></li><li><p>避免对大表查询时进行 <code>table scan</code>,必要时考虑新建索引;</p></li><li><p>在使用索引字段作为条件时,如果该索引是联合索引,那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引,否则该索引将不会被使用;</p></li><li><p>要注意索引的维护,周期性重建索引,重新编译存储过程。 </p></li></ul><p>29、下列 SQL 条件语句中的列都建有恰当的索引,但执行速度却非常慢:<br/></p><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:sql;toolbar:false">SELECT * FROM record WHERE substrINg(card_no, 1, 4) = '5378' --13秒
SELECT * FROM record WHERE amount/30 < 1000 --11秒
SELECT * FROM record WHERE convert(char(10), date, 112) = '19991201' --10秒</pre><div class="contentsignin">로그인 후 복사</div></div><div class="contentsignin">로그인 후 복사</div></div><p>分析: WHERE 子句中对列的任何操作结果都是在 SQL 运行时逐列计算得到的,因此它不得不进行表搜索,而没有使用该列上面的索引。如果这些结果在查询编译时就能得到,那么就可以被 SQL 优化器优化,使用索引,避免表搜索,因此将 SQL 重写成下面这样:</p><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:sql;toolbar:false">SELECT * FROM record WHERE card_no like '5378%' -- < 1秒
SELECT * FROM record WHERE amount < 1000*30 -- < 1秒
SELECT * FROM record WHERE date = '1999/12/01' -- < 1秒</pre><div class="contentsignin">로그인 후 복사</div></div><p>30、当有一批处理的插入或更新时,用批量插入或批量更新,绝不会一条条记录的去更新。</p>
<p>31、在所有的存储过程中,能够用 SQL 语句的,绝不用循环去实现。<br></p>
<p>32、选择最有效率的表名顺序(只在基于规则的优化器中有效): </p>
<p>Oracle 的解析器按照从右到左的顺序处理 FROM 子句中的表名,FROM 子句中写在最后的表(基础表 driving table)将被最先处理,在 FROM 子句中包含多个表的情况下,必须选择记录条数最少的表作为基础表。<strong>如果有 3 个以上的表连接查询,那就需要选择交叉表(intersection table)作为基础表</strong>,交叉表是指那个被其他表所引用的表。</p>
<p>33、提高<code> GROUP BY</code> 语句的效率,可以通过将不需要的记录在 GROUP BY 之前过滤掉。<br></p>
<p>34、<strong>SQL 语句用大写</strong>,因为 Oracle 总是先解析 SQL 语句,把小写的字母转换成大写的再执行。</p>
<p>35、别名的使用,别名是大型数据库的应用技巧,就是表名、列名在查询中以一个字母为别名,查询速度要比建连接表快 1.5 倍。<br></p>
<p>36、避免死锁,在你的存储过程和触发器中访问同一个表时总以相同的顺序;事务应尽可能地缩短,减少数据量的涉及;永远不要在事务中等待用户输入。<br></p>
<p>37、避免使用临时表,除非有需要,可以使用表变量代替。大多数时候(99%),表变量驻扎在内存中,因此速度比临时表更快,临时表驻扎在 TempDb 数据库中,因此临时表上的操作需要跨数据库通信,速度自然慢。<br></p>
<p>38、最好不要使用触发器:<br></p>
<ul style="list-style-type: disc;">
<li><p>触发,执行一个触发器事件本身就是一个耗费资源的过程;<br>
</p></li>
<li><p>如果能够使用约束实现的,尽量不要使用触发器;</p></li>
<li><p>不要为不同的触发事件(<code>Insert、Update 和 Delete</code>)使用相同的触发器;</p></li>
<li><p>트리거에 트랜잭션 코드를 사용하지 마세요. </p></li>
</ul>
<p>39. 인덱스 생성 규칙: <br></p>
<ul style="list-style-type: disc;">
<li><p>테이블의 기본 키와 외래 키에는 인덱스가 있어야 합니다.
<br></p></li>
<li>데이터 볼륨이 300개가 넘는 테이블에는 인덱스가 있어야 합니다. <p></p>
</li>
<li>다른 테이블에 자주 연결되는 테이블에는 연결 필드에 인덱스가 있어야 합니다. <p></p>
</li>
<li>WHERE 절에 자주 나타나는 필드, 특히 필드 이는 큰 테이블의 필드이며 색인이 생성되어야 합니다. <p></p>
</li>
<li>색인은 매우 선택적인 필드에 작성되어야 합니다. <p></p>
</li>
<li>큰 텍스트 필드 또는 매우 긴 필드에 대해서는 색인을 작성하지 마십시오. 인덱스 구축 <p></p>
</li>
<li>복합 인덱스를 설정하려면 신중한 분석이 필요하며 대신 단일 필드 인덱스 사용을 고려해 보세요. <p></p>
</li>
<li>복합 인덱스에서 기본 열 필드를 올바르게 선택하세요. 더 나은 선택성 <p></p>
</li>
<li>복합 인덱스의 여러 필드가 AND 모드의 WHERE 절에 동시에 나타나는 경우가 자주 있습니까? 단일 필드 쿼리가 거의 없거나 전혀 없나요? 그렇다면 복합 인덱스를 구축할 수 있습니다. 그렇지 않으면 단일 필드 인덱스를 고려하세요. <p></p>
</li>
<li>복합 인덱스에 포함된 필드가 WHERE 절에 단독으로 나타나는 경우가 있으면 이를 여러 단일 필드 인덱스로 분해하세요. <p></p>복합 인덱스가 3개 이상의 필드를 포함하는 경우 필요성을 신중히 고려하여 복합 필드 수를 줄이세요. </li>
<li>
<p></p>이 필드에 단일 필드 인덱스와 복합 인덱스가 모두 있는 경우 일반적으로 삭제할 수 있습니다. </li> <li>
<p></p>데이터 작업이 자주 발생하는 테이블의 경우 인덱스를 너무 많이 생성하지 마세요. </li>
<li>
<p></p>실행 계획에 부정적인 영향을 주지 않도록 불필요한 인덱스를 삭제하세요. 스토리지 오버헤드가 증가합니다. 인덱스는 삽입, 삭제 및 업데이트 작업에 대한 처리 오버헤드도 증가합니다. 또한 단일 필드 인덱스가 있는 경우 일반적으로 너무 많은 복합 인덱스는 가치가 없습니다. 반대로 데이터를 추가하고 삭제할 때 성능이 저하되며, 특히 자주 업데이트되는 테이블의 경우 부정적인 영향이 더욱 커집니다. . </li>
<li>
<p></p>중복 값이 많이 포함된 데이터베이스의 필드를 색인화하지 마세요. </li>
<li>
<p></p>40. MySQL 쿼리 최적화 요약: </li>
<li><p></p></li>느린 쿼리 로그를 사용하여 느린 쿼리를 찾고, 실행 계획을 사용하여 쿼리가 정상적으로 실행되고 있는지 확인하고, 항상 쿼리를 테스트하여 최적의 상태로 실행되고 있는지 확인하세요. </ul>
<p><br></p>
<ul style="list-style-type: disc;">성능은 시간이 지남에 따라 변경됩니다. 전체 테이블에서 <li> 사용을 피하고, WHERE, GROUP BY 및 ORDER BY 절에 인덱스 열을 사용하고, 인덱스를 단순하게 유지하고, 여러 인덱스에 동일한 열을 포함하지 마세요. <p>
<br></p>
</li>
<li>때때로 MySQL은 잘못된 인덱스를 사용합니다. 이 경우 <p>를 사용하는 것은 OR이 아닙니다. <code>count(*)</code>,它可能锁住整张表,使查询保持一致以便后续相似的查询可以使用查询缓存,在适当的情形下使用 <code>GROUP BY</code> 而不是 <code>DISTINCT</code>
<br></p>
</li>
<li>업데이트 전에 SELECT를 피하려면 <p>를 사용하면 N이 실제로 쿼리 속도를 늦출 수 있습니다. 드물게 사용하고, 하위 쿼리 대신 WHERE 절에 UNION을 사용하고, MySQL을 다시 시작할 때 데이터베이스를 워밍업하여 데이터가 메모리 및 쿼리 속도가 빠르면 오버헤드를 줄이기 위해 여러 연결 대신 영구 연결을 고려하십시오. <code>USE INDEX</code>,检查使用 <code>SQL_MODE=STRICT</code> 的问题,对于记录数小于5的索引字段,在 UNION 的时候使用<code>LIMIT</code>
<br></p>
</li>
<li>벤치마크 쿼리, 서버 부하 사용 포함, 때로는 간단한 쿼리가 다른 쿼리에 영향을 미칠 수 있음, 서버 부하가 증가하면 <p>를 사용하여 느린 쿼리 및 문제가 있는 쿼리 보기, 개발 환경에서 생성된 미러 데이터 모두 의심스러운 쿼리가 테스트되었습니다. <code>INSERT ON DUPLICATE KEY</code> 或者 <code>INSERT IGNORE</code>;不要用 UPDATE 去实现,不要使用 MAX;使用索引字段和 <code>ORDER BY</code>子句 <code>LIMIT M</code>
<br></p>
</li>
<li>41. MySQL 백업 프로세스: <p><code>SHOW PROCESSLIST</code><br></p>
</li>보조 복제 서버에서 백업;
</ul>
<p><br></p>데이터 종속성 및 외래 키 제약 조건의 불일치를 방지하려면 백업 중 복제를 중지하세요. <ul style="list-style-type: disc;">
<li><p><br>MySQL을 완전히 중지하고 데이터베이스 파일에서 백업하세요. </p></li>
<li><p>백업에 MySQL 덤프를 사용하는 경우 동시에 다음을 수행하세요. 복제가 중단되지 않도록 바이너리 로그 파일을 백업하십시오. </p></li>
<li><p>향후 문제를 일으킬 수 있는 데이터 불일치가 발생할 수 있는 LVM 스냅샷을 신뢰하지 마십시오. -테이블 복구가 더 쉬워집니다. 데이터가 다른 테이블과 격리된 경우 데이터를 테이블 단위로 내보냅니다. </p></li>
<li>
<p>사용 시 </p>;</li>
<li>
<p></p>백업 전 테이블 확인 및 최적화;</li>
<li><p>더 빠른 가져오기를 위해 가져오는 동안 외래 키 제약 조건과 고유성 감지가 일시적으로 비활성화됩니다. </p></li>
<li>
<p> 데이터 크기 증가를 모니터링할 수 있도록 각 백업 후 데이터베이스, 테이블 및 인덱스의 크기를 계산합니다. </p>정기적인 백업을 수행하세요. </li>
<li>
<p></p>42. 쿼리 버퍼는 공백을 자동으로 처리하지 않습니다. 따라서 SQL 문을 작성할 때 공백의 사용을 줄여야 합니다. 특히 SQL의 시작과 끝 부분에 있는 공백은 쿼리 캐시가 자동으로 처리하지 않기 때문입니다. 시작과 끝의 공백을 가로채세요). </li>
</ul>
<p>43. 회원은 mid를 기준으로 테이블을 테이블로 나누어 쉽게 쿼리할 수 있나요? 일반적인 비즈니스 요구 사항에서는 기본적으로 사용자 이름을 쿼리 기반으로 사용합니다. 일반적으로 사용자 이름은 테이블을 분할하는 해시 모듈러스로 사용해야 합니다. 테이블 파티셔닝의 경우 MySQL의 <code>partition</code> 함수가 이를 수행하며 코드에 투명하므로 코드 수준에서 구현하는 것은 무리인 것 같습니다. <br></p>44. 데이터베이스의 각 테이블에 대한 기본 키로 ID를 설정해야 하며 가장 좋은 것은 INT 유형(<code>UNSIGNED</code> 권장)이며 <code>가 자동으로 증가하도록 설정합니다. AUTO_INCREMENT</code> 플래그. <p><code>partition</code> 功能就是干这个的,对代码是透明的;在代码层面去实现貌似是不合理的。</p>
<p>44、我们应该为数据库里的每张表都设置一个 ID 做为其主键,而且最好的是一个 INT 型的(推荐使用 <code>UNSIGNED</code>),并设置上自动增加的 <code>AUTO_INCREMENT</code> 标志。<br></p>
<p>45、在所有的存储过程和触发器的开始处设置 <code>SET NOCOUNT ON</code>,在结束时设置 <code>SET NOCOUNT OFF</code>。无需在执行存储过程和触发器的每个语句后向客户端发送 <code>DONE_IN_PROC</code> 消息。<br></p>
<p>46、MySQL 查询可以启用高速查询缓存。这是提高数据库性能的有效MySQL优化方法之一。当同一个查询被执行多次时,从缓存中提取数据和直接从数据库中返回数据快很多。<br></p>
<p>47、<code>EXPLAIN SELECT</code> 查询用来跟踪查看效果:<br></p>
<p>使用 EXPLAIN 关键字可以让你知道 MySQL 是如何处理你的 SQL 语句的。这可以帮你分析你的查询语句或是表结构的性能瓶颈。EXPLAIN 的查询结果还会告诉你你的索引主键被如何利用的,你的数据表是如何被搜索和排序的。<br></p>
<p>48、当只要一行数据时使用 LIMIT 1 :<br></p>
<p>当你查询表的有些时候,你已经知道结果只会有一条结果,但因为你可能需要去fetch游标,或是你也许会去检查返回的记录数。在这种情况下,加上 <code>LIMIT 1 </code>可以增加性能。这样一来,MySQL 数据库引擎会在找到一条数据后停止搜索,而不是继续往后查少下一条符合记录的数据。</p>
<p>49、选择表合适存储引擎: <br></p>
<p><strong>myisam:</strong>应用时以读和插入操作为主,只有少量的更新和删除,并且对事务的完整性,并发性要求不是很高的。 <br></p>
<p><strong>InnoDB:</strong>事务处理,以及并发条件下要求数据的一致性。除了插入和查询外,包括很多的更新和删除。(InnoDB 有效地降低删除和更新导致的锁定)。</p>
<p>对于支持事务的 InnoDB类 型的表来说,影响速度的主要原因是 <code>AUTOCOMMIT</code> 默认设置是打开的,而且程序没有显式调用 BEGIN 开始事务,导致每插入一条都自动提交,严重影响了速度。可以在执行 SQL 前调用 begin,多条 SQL 形成一个事物(即使 autocommit 打开也可以),将大大提高性能。</p>
<p>50、优化表的数据类型,选择合适的数据类型: <br></p>
<p><strong>原则:</strong>更小通常更好,简单就好,所有字段都得有默认值,尽量避免 NULL。 MySQL可以很好的支持大数据量的存取,但是一般来说,数据库中的表越小,在它上面执行的查询也就会越快。 因此,在创建表的时候,为了获得更好的性能,我们可以将表中字段的宽度设得尽可能小。</p>
<p>同样的,如果可以的话,我们应该使用 <code>MEDIUMINT </code>而不是 <code>BIGIN </code>来定义整型字段,应该尽量把字段设置为 <code>NOT NULL</code>,这样在将来执行查询的时候,数据库不用去比较 NULL 值。 </p>
<p>对于某些文本字段,例如“省份”或者“性别”,我们可以将它们定义为 <code>ENUM </code><br>45. 모든 저장 프로시저 및 트리거의 시작 부분에 <code>SET NOCOUNT ON</code>을 설정하고 끝 부분에 <code>SET NOCOUNT OFF</code>를 설정하세요. 저장 프로시저 및 트리거의 각 문 후에 클라이언트에 <code>DONE_IN_PROC</code> 메시지를 보낼 필요가 없습니다. </p>
<p><br>46. MySQL 쿼리는 고속 쿼리 캐시를 활성화할 수 있습니다. 이는 데이터베이스 성능을 향상시키는 효과적인 MySQL 최적화 방법 중 하나입니다. 동일한 쿼리를 여러 번 실행하는 경우 캐시에서 데이터를 가져와 데이터베이스에서 직접 반환하는 것이 훨씬 빠릅니다. </p>
<p></p>47. <code>EXPLAIN SELECT</code> 쿼리는 보기 효과를 추적하는 데 사용됩니다. <p><a href="https://www.php.cn/mysql-tutorials.html" target="_self"></a> EXPLAIN 키워드를 사용하면 MySQL이 SQL 문을 처리하는 방법을 알 수 있습니다. 이는 쿼리 문이나 테이블 구조의 성능 병목 현상을 분석하는 데 도움이 될 수 있습니다. EXPLAIN 쿼리 결과는 인덱스 기본 키가 사용되는 방법과 데이터 테이블이 검색 및 정렬되는 방법도 알려줍니다. </p>🎜🎜48. 데이터 행이 하나만 있는 경우 LIMIT 1을 사용하세요. 🎜🎜🎜때때로 테이블을 쿼리할 때 결과가 하나뿐이라는 것을 이미 알고 있지만 커서를 가져와야 할 수도 있습니다. 가셔도 됩니다. 반환된 레코드 수를 확인하세요. 이 경우 <code>LIMIT 1 </code>을 추가하면 성능이 향상될 수 있습니다. 이러한 방식으로 MySQL 데이터베이스 엔진은 레코드와 일치하는 다음 데이터 조각을 계속 검색하는 대신 데이터 조각을 찾은 후 검색을 중지합니다. 🎜🎜49 테이블에 적합한 스토리지 엔진을 선택하세요. 🎜🎜🎜<strong>myisam:</strong> 이 애플리케이션은 주로 읽기 및 삽입 작업을 기반으로 하며 약간의 업데이트 및 삭제와 무결성 및 트랜잭션의 동시성 요구 사항은 매우 높지 않습니다. 🎜🎜🎜<strong>InnoDB:</strong> 동시 조건에서 트랜잭션 처리 및 데이터 일관성이 필요합니다. 삽입 및 쿼리 외에도 많은 업데이트 및 삭제도 포함됩니다. (InnoDB는 삭제 및 업데이트로 인한 잠금을 효과적으로 줄입니다.) 🎜🎜트랜잭션을 지원하는 InnoDB 유형 테이블의 경우 속도에 영향을 미치는 주된 이유는 <code>AUTOCOMMIT</code>의 기본 설정이 켜져 있고 프로그램이 트랜잭션을 시작하기 위해 BEGIN을 명시적으로 호출하지 않기 때문입니다. 삽입이 자동으로 제출되므로 속도에 심각한 영향을 미칩니다. SQL을 실행하기 전에 start를 호출하면 여러 SQL이 하나의 형태를 이루므로(자동 커밋이 켜져 있는 경우에도) 성능이 크게 향상됩니다. 🎜🎜50. 테이블의 데이터 유형을 최적화하고 적절한 데이터 유형을 선택하세요. 🎜🎜🎜<strong>원칙:</strong> 일반적으로 작을수록 좋고, 단순할수록 좋습니다. 모든 필드에는 기본값이 있어야 하며 피하려고 노력하세요. NULL. MySQL은 많은 양의 데이터에 대한 액세스를 매우 잘 지원할 수 있지만 일반적으로 데이터베이스의 테이블이 작을수록 쿼리 실행 속도가 빨라집니다. 따라서 테이블을 생성할 때 더 나은 성능을 얻기 위해 테이블의 필드 너비를 최대한 작게 설정할 수 있습니다. 🎜🎜마찬가지로 가능하다면 <code>BIGIN </code> 대신 <code>MEDIUMINT </code>를 사용하여 정수 필드를 정의해야 하며 필드를 <code>NOT NULL</code>로 설정해야 합니다. >, 향후 쿼리 실행 시 데이터베이스가 NULL 값을 비교할 필요가 없도록 하기 위함입니다. 🎜🎜"지방" 또는 "성별"과 같은 일부 텍스트 필드의 경우 <code>ENUM </code> 유형으로 정의할 수 있습니다. 왜냐하면 MySQL에서는 ENUM 유형이 숫자 데이터로 처리되고, 숫자 데이터는 텍스트 유형보다 훨씬 빠르게 처리되기 때문입니다. 이러한 방식으로 데이터베이스의 성능을 향상시킬 수 있습니다. 🎜🎜🎜51. 문자열 데이터 유형: char, varchar, text. 🎜🎜🎜52. 열에 대한 모든 작업은 데이터베이스 함수, 계산 표현식 등을 포함하는 테이블 스캔으로 이어집니다. 쿼리할 때 작업을 최대한 등호 오른쪽으로 이동하세요. 🎜🎜추천 튜토리얼: "🎜MySQL 튜토리얼🎜"🎜