Heim > Schlagzeilen > 52 SQL-Optimierungsstrategien, die es wert sind, gesammelt zu werden, um die Leistung zu verbessern

52 SQL-Optimierungsstrategien, die es wert sind, gesammelt zu werden, um die Leistung zu verbessern

醉折花枝作酒筹
Freigeben: 2021-03-24 16:15:51
nach vorne
7937 Leute haben es durchsucht
<p>SQL-Anweisungen können Daten manipulieren und Daten definieren, was den Benutzern großen Komfort bieten kann. In diesem Artikel werden 52 Strategien zur Leistungsoptimierung von SQL-Anweisungen erwähnt. Freunden in Not wird empfohlen, es abzuholen. </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>Strategie zur Optimierung der SQL-Anweisungsleistung</strong></span></p> <p>1. Um die Abfrage zu optimieren, sollten Sie zunächst <code>WHERE</code> und <code> ORDER BY berücksichtigen Code> erstellt einen Index für die beteiligten Spalten. <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">Nach dem Login kopieren</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">Nach dem Login kopieren</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>,读、写是会相互阻塞的,为了提高并发性能。对于一些查询,可以加上 nolock,这样读的时候可以允许写,但缺点是可能读到未提交的脏数据。<br/></p><p>使用 nolock 有3条原则:</p><ul style="list-style-type: disc;"><li><p>查询的结果用于“插、删、改”的不能加 nolock;<br/> </p></li><li><p>查询的表属于频繁发生页分裂的,慎用 nolock ;</p></li><li><p>使用临时表一样可以保存“数据前影”,起到类似 Oracle 的 undo 表空间的功能,能采用临时表提高并发性能的,不要用 nolock。</p></li></ul><p>19、常见的简化规则如下:不要有超过 5 个以上的表连接(<code>JOIN</code>),考虑使用临时表或表变量存放中间结果。少用子查询,视图嵌套不要过深,一般视图嵌套不要超过 2 个为宜。</p><p>20、将需要查询的结果预先计算好放在表中,查询的时候再<code>Select</code></p>2. Versuchen Sie, NULL-Werturteile für Felder in der WHERE-Klausel zu vermeiden. NULL ist der Standardwert beim Erstellen einer Tabelle. In den meisten Fällen sollten Sie jedoch <code> NOT NULL</code> verwenden Wert, beispielsweise <code>0</code>, <code>-1</code> als Standardwert. <br/>🎜🎜3. Vermeiden Sie die Verwendung der Operatoren != oder <> MySQL verwendet Indizes nur für die folgenden Operatoren: <code><</code>, <code><=</code>, <code>=</code>, <code>></code>, < code>>=</code>, <code>BETWEEN</code>, <code>IN</code> und manchmal <code>LIKE</code>. <br/>🎜🎜4. Vermeiden Sie die Verwendung von OR in der WHERE-Klausel, um Bedingungen zu verbinden, da die Engine sonst die Verwendung des Index aufgibt und einen vollständigen Tabellenscan durchführt. Sie können UNION verwenden, um Abfragen zusammenzuführen. <br/>🎜🎜5. IN und NOT IN sollten ebenfalls mit Vorsicht verwendet werden, da es sonst zu einem vollständigen Tabellenscan kommt. Verwenden Sie für kontinuierliche Werte nicht IN, wenn Sie BETWEEN verwenden können. <br/>🎜🎜6. Die folgende Abfrage führt ebenfalls zu einem vollständigen Tabellenscan: 🎜<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 = &#39;JCNPRH39681&#39; (A = B, B = &#39;号码&#39;) select a.personMemberID, * from chineseresume a,personmember b where a.personMemberID = b.referenceid and a.personMemberID = &#39;JCNPRH39681&#39; and b.referenceid = &#39;JCNPRH39681&#39; (A = B, B = &#39;号码&#39;, A = &#39;号码&#39;) select a.personMemberID, * from chineseresume a,personmember b where b.referenceid = &#39;JCNPRH39681&#39; and a.personMemberID = &#39;JCNPRH39681&#39; (B = &#39;号码&#39;, A = &#39;号码&#39;)</pre><div class="contentsignin">Nach dem Login kopieren</div></div><div class="contentsignin">Nach dem Login kopieren</div></div>🎜<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) = &#39;5378&#39; --13秒 SELECT * FROM record WHERE amount/30 < 1000 --11秒 SELECT * FROM record WHERE convert(char(10), date, 112) = &#39;19991201&#39; --10秒</pre><div class="contentsignin">Nach dem Login kopieren</div></div><div class="contentsignin">Nach dem Login kopieren</div></div>🎜7. Wenn Parameter in der WHERE-Klausel verwendet werden, führt dies ebenfalls zu einem vollständigen Tabellenscan. 🎜🎜8. Vermeiden Sie Ausdrucksoperationen und Funktionsoperationen für Felder in der WHERE-Klausel. <br/>🎜🎜9. Oft ist es eine gute Wahl, <code>EXISTS </code> anstelle von IN zu verwenden. <br/>🎜🎜10. Obwohl der Index die Effizienz des entsprechenden SELECT verbessern kann, reduziert er auch den <code>INSERT </code> und den <code>UPDATE </code>. Da der Index während INSERT oder UPDATE möglicherweise neu erstellt wird, ist es am besten, nicht mehr als 6 Indizes für eine Tabelle zu haben. <br/>🎜🎜11. Sie sollten die Aktualisierung von <code>Cluster-Index-Datenspalten</code> so weit wie möglich vermeiden, da die Reihenfolge der Cluster-Index-Datenspalten die physische Speicherreihenfolge von Tabellendatensätzen ist, sobald sich der Spaltenwert ändert , wird die gesamte Tabelle betroffen sein. Das Anpassen der Aufzeichnungsreihenfolge wird erhebliche Ressourcen verbrauchen. <br/>🎜🎜12. Versuchen Sie, numerische Typen zu verwenden, die nur numerische Informationen enthalten. Dies verringert die Leistung von Abfragen und Verbindungen und erhöht den Speicherplatz. <br/>🎜🎜13. Verwenden Sie so oft wie möglich <code>varchar</code>, <code>nvarchar</code> anstelle von <code>char</code>, <code>nchar</code>. Denn erstens haben lange Felder wenig Speicherplatz und können Speicherplatz sparen. Bei Abfragen ist die Suche in einem relativ kleinen Feld offensichtlich effizienter. <br/>🎜🎜14. Am besten verwenden Sie nicht „return all“: <code>select from t</code>, ersetzen Sie „*“ durch eine bestimmte Feldliste und geben Sie keine nicht verwendeten Felder zurück. <br/>🎜🎜15. Vermeiden Sie die Rückgabe großer Datenmengen an den Kunden. Wenn die Datenmenge zu groß ist, sollten Sie überlegen, ob die entsprechenden Anforderungen angemessen sind. <br/>🎜🎜16. Verwenden Sie Tabellenaliase (Alias): Wenn Sie mehrere Tabellen in einer SQL-Anweisung verbinden, verwenden Sie bitte Tabellenaliase und stellen Sie den Aliasnamen jeder <code> Spalte</code> voran. Dies verkürzt die Analysezeit und reduziert Syntaxfehler, die durch Mehrdeutigkeiten in den Spalten verursacht werden. <br/>🎜🎜17. Verwenden Sie „temporäre Tabelle“, um Zwischenergebnisse vorübergehend zu speichern. <br/>🎜🎜Eine wichtige Möglichkeit zur Vereinfachung von SQL-Anweisungen besteht darin, temporäre Tabellen zum vorübergehenden Speichern von Zwischenergebnissen zu verwenden. Speichern Sie die temporären Ergebnisse vorübergehend in der temporären Tabelle, und nachfolgende Abfragen erfolgen in <code>tempdb</code>. Dadurch kann vermieden werden, dass die Haupttabelle mehrmals im Programm gescannt wird, und die Blockierung durch „gemeinsame Sperren“ wird erheblich reduziert. Aktualisierungssperre während der Programmausführung. ”, Reduzierung der Blockierung und Verbesserung der Parallelitätsleistung. <br/>🎜🎜18. Einige SQL-Abfrageanweisungen sollten mit <code>nolock</code> hinzugefügt werden, um die Parallelitätsleistung zu verbessern. Für einige Abfragen können Sie Nolock hinzufügen, was das Schreiben beim Lesen ermöglicht. Der Nachteil besteht jedoch darin, dass nicht festgeschriebene schmutzige Daten gelesen werden können. <br/>🎜🎜Es gibt drei Prinzipien für die Verwendung von Nolock: 🎜<ul style="list-style-type: disc;"><li>🎜Wenn die Abfrageergebnisse für „Einfügung, Löschung und Änderung“ verwendet werden, nolock kann nicht hinzugefügt werden; <br/> 🎜</li><li>🎜In der abgefragten Tabelle kommt es häufig zu Seitenaufteilungen, also verwenden Sie nolock mit Vorsicht. 🎜</li><li>🎜Die Verwendung einer temporären Tabelle kann auch den „Datenvorschlag“ speichern ähnlich dem Rückgängigmachen von Oracle Verwenden Sie für Tabellenbereichsfunktionen, die temporäre Tabellen verwenden können, um die Parallelitätsleistung zu verbessern, kein Nolock. 🎜</li></ul>🎜19. Gängige Vereinfachungsregeln sind wie folgt: Verwenden Sie nicht mehr als 5 Tabellenverbindungen (<code>JOIN</code>) und erwägen Sie die Verwendung temporärer Tabellen oder Tabellenvariablen zum Speichern von Zwischenergebnissen . Verwenden Sie weniger Unterabfragen und verschachteln Sie Ansichten nicht zu tief. Im Allgemeinen ist es sinnvoll, nicht mehr als zwei Ansichten zu verschachteln. 🎜🎜20. Berechnen Sie die abzufragenden Ergebnisse vorab, geben Sie sie in die Tabelle ein und klicken Sie dann bei der Abfrage auf <code>Auswählen</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 = &#39;JCNPRH39681&#39; (A = B, B = &#39;号码&#39;) select a.personMemberID, * from chineseresume a,personmember b where a.personMemberID = b.referenceid and a.personMemberID = &#39;JCNPRH39681&#39; and b.referenceid = &#39;JCNPRH39681&#39; (A = B, B = &#39;号码&#39;, A = &#39;号码&#39;) select a.personMemberID, * from chineseresume a,personmember b where b.referenceid = &#39;JCNPRH39681&#39; and a.personMemberID = &#39;JCNPRH39681&#39; (B = &#39;号码&#39;, A = &#39;号码&#39;)</pre><div class="contentsignin">Nach dem Login kopieren</div></div><div class="contentsignin">Nach dem Login kopieren</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) = &#39;5378&#39; --13秒 SELECT * FROM record WHERE amount/30 < 1000 --11秒 SELECT * FROM record WHERE convert(char(10), date, 112) = &#39;19991201&#39; --10秒</pre><div class="contentsignin">Nach dem Login kopieren</div></div><div class="contentsignin">Nach dem Login kopieren</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 &#39;5378%&#39; -- < 1秒 SELECT * FROM record WHERE amount < 1000*30 -- < 1秒 SELECT * FROM record WHERE date = &#39;1999/12/01&#39; -- < 1秒</pre><div class="contentsignin">Nach dem Login kopieren</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>Verwenden Sie keinen Transaktionscode in Triggern. </p></li> </ul> <p>39. Regeln zur Indexerstellung: <br></p> <ul style="list-style-type: disc;"> <li><p>Der Primärschlüssel und der Fremdschlüssel der Tabelle müssen Indizes haben <br> </p></li> <li><p>Tabellen mit mehr als 300 Datenmengen sollten Indizes haben; </p></li> <li><p>Tabellen, die häufig mit anderen Tabellen verbunden sind, sollten Indizes für die Verbindungsfelder haben; </p></li> <li><p>Felder, die häufig in der WHERE-Klausel vorkommen, insbesondere Felder Es handelt sich um ein Feld einer großen Tabelle und sollte indiziert werden. </p></li> <li><p>Indizes sollten auf sehr selektiven Feldern erstellt werden. </p></li> <li><p>Indizes sollten auf kleinen Feldern oder sogar auf sehr langen Feldern erstellt werden Erstellen Sie Indizes. </p></li> <li><p>Die Erstellung eines zusammengesetzten Index erfordert eine sorgfältige Analyse. Versuchen Sie stattdessen, einen Einzelfeldindex zu verwenden. </p></li> <li><p>Wählen Sie das Hauptspaltenfeld im zusammengesetzten Index richtig aus bessere Selektivität; </p></li> <li><p>Compound Kommen in der WHERE-Klausel im AND-Modus oft mehrere Felder des Index vor? Gibt es wenige oder keine Einzelfeldabfragen? Wenn ja, können Sie einen zusammengesetzten Index erstellen. Andernfalls sollten Sie einen Einzelfeldindex in Betracht ziehen </p></li>Wenn der zusammengesetzte Index mehr als 3 Felder enthält, prüfen Sie sorgfältig die Notwendigkeit und reduzieren Sie die Anzahl der zusammengesetzten Felder. <li><p></p></li>Wenn für diese Felder sowohl Einzelfeldindizes als auch zusammengesetzte Indizes vorhanden sind, können Sie diese im Allgemeinen löschen der zusammengesetzte Index; <li> <p></p>Erstellen Sie für Tabellen, die häufigen Datenoperationen unterliegen, nicht zu viele Indizes. </li> <li> <p></p>Löschen Sie nutzlose Indizes, um negative Auswirkungen auf den Ausführungsplan zu vermeiden erhöhen den Speicheraufwand. Indizes erhöhen auch den Verarbeitungsaufwand für Einfüge-, Lösch- und Aktualisierungsvorgänge. Darüber hinaus sind zu viele zusammengesetzte Indizes im Allgemeinen wertlos, wenn Einzelfeldindizes vorhanden sind. Im Gegenteil, sie verringern auch die Leistung beim Hinzufügen und Löschen von Daten, insbesondere bei häufig aktualisierten Tabellen. Die negativen Auswirkungen sind noch größer . </li> <li> <p></p>Versuchen Sie, ein Feld in der Datenbank nicht zu indizieren, das eine große Anzahl doppelter Werte enthält. </li> <li> <p></p>40. Zusammenfassung der MySQL-Abfrageoptimierung: </li> <li><p></p></li>Verwenden Sie langsame Abfrageprotokolle, um langsame Abfragen zu finden, verwenden Sie Ausführungspläne, um festzustellen, ob Abfragen normal ausgeführt werden, und testen Sie Ihre Abfragen stets, um festzustellen, ob sie im optimalen Zustand ausgeführt werden. <li> <p></p> </li> </ul>Die Leistung ändert sich im Laufe der Zeit. Vermeiden Sie die Verwendung von <code>count(*)</code> für die gesamte Tabelle. Dadurch wird möglicherweise die gesamte Tabelle gesperrt, wodurch die Abfrage konsistent wird, sodass nachfolgende ähnliche Abfragen den Abfragecache verwenden können. Verwenden Sie ggf. <code>GROUP BY</code> anstelle von <code>DISTINCT</code>, verwenden Sie indizierte Spalten in WHERE-, GROUP BY- und ORDER BY-Klauseln, halten Sie Indizes einfach und verwenden Sie nicht mehrere Indizes, die dasselbe enthalten Spalte. <p> <br></p> <ul style="list-style-type: disc;"> <li>Manchmal verwendet MySQL den falschen Index. Verwenden Sie in diesem Fall <code>USE INDEX</code>. Überprüfen Sie das Problem bei der Verwendung von <code>SQL_MODE=STRICT</code> für Indizes mit weniger als 5 Datensätzen Wenn Sie UNION verwenden, verwenden Sie <code>LIMIT</code> anstelle von OR. <p> <br></p> </li> <li>Um SELECT vor der Aktualisierung zu vermeiden, verwenden Sie <code>INSERT ON DUPLICATE KEY</code> oder <code>INSERT IGNORE</code>, verwenden Sie nicht UPDATE zur Implementierung, verwenden Sie keine Indexfelder und <code>ORDER BY</code>-Klausel <code>LIMIT M</code>, N kann die Abfrage in einigen Fällen tatsächlich verlangsamen, sparsam verwenden, UNION in der WHERE-Klausel anstelle der Unterabfrage verwenden, neu starten. Denken Sie bei MySQL daran um Ihre Datenbank aufzuwärmen, um sicherzustellen, dass sich die Daten im Speicher befinden und Abfragen schnell erfolgen, und ziehen Sie dauerhafte Verbindungen statt mehrerer Verbindungen in Betracht, um den Overhead zu reduzieren. <p> <code>count(*)</code>,它可能锁住整张表,使查询保持一致以便后续相似的查询可以使用查询缓存,在适当的情形下使用 <code>GROUP BY</code> 而不是 <code>DISTINCT</code>,在 WHERE、GROUP BY 和 ORDER BY 子句中使用有索引的列,保持索引简单,不在多个索引中包含同一个列。<br>        </p> </li> <li><p>有时候 MySQL 会使用错误的索引,对于这种情况使用 <code>USE INDEX</code>,检查使用 <code>SQL_MODE=STRICT</code> 的问题,对于记录数小于5的索引字段,在 UNION 的时候使用<code>LIMIT</code>不是是用OR。 <br>        </p></li> <li><p>为了避免在更新前 SELECT,使用 <code>INSERT ON DUPLICATE KEY</code> 或者 <code>INSERT IGNORE</code>;不要用 UPDATE 去实现,不要使用 MAX;使用索引字段和 <code>ORDER BY</code>子句 <code>LIMIT M</code>,N 实际上可以减缓查询在某些情况下,有节制地使用,在 WHERE 子句中使用 UNION 代替子查询,在重新启动的 MySQL,记得来温暖你的数据库,以确保数据在内存和查询速度快,考虑持久连接,而不是多个连接,以减少开销。<br>        </p></li> <li><p>基准查询,包括使用服务器上的负载,有时一个简单的查询可以影响其他查询,当负载增加在服务器上,使用 <code>SHOW PROCESSLIST</code> 查看慢查询和有问题的查询,在开发环境中产生的镜像数据中测试的所有可疑的查询。<br>        </p></li> </ul> <p>41、MySQL 备份过程:<br></p> <ul style="list-style-type: disc;"> <li><p>从二级复制服务器上进行备份;<br>        </p></li> <li><p>在进行备份期间停止复制,以避免在数据依赖和外键约束上出现不一致;</p></li> <li><p>彻底停止 MySQL,从数据库文件进行备份;</p></li> <li><p>如果使用 MySQL dump 进行备份,请同时备份二进制日志文件,确保复制没有中断;</p></li> <li><p>不要信任 LVM 快照,这很可能产生数据不一致,将来会给你带来麻烦;</p></li> <li><p>为了更容易进行单表恢复,如果数据是与其他表隔离的,以表为单位导出数据。 </p></li> <li><p>当使用 <code>mysqldump</code> 时请使用 <code>–opt</code></p></li> <li>Benchmark-Abfragen, einschließlich der Verwendung der Auslastung des Servers. Manchmal kann sich eine einfache Abfrage auf andere Abfragen auswirken. Wenn die Auslastung des Servers zunimmt, verwenden Sie <code>SHOW PROCESSLIST</code>, um langsame und problematische Abfragen anzuzeigen. Testen Sie alle verdächtigen Abfragen der in der Entwicklungsumgebung generierten Bilddaten. <p> ​ ​ </p>🎜🎜🎜41. MySQL-Sicherungsvorgang: 🎜🎜🎜🎜🎜Sicherung vom sekundären Replikationsserver 🎜 🎜🎜🎜🎜Stoppen Sie die Replikation während der Sicherung, um Inkonsistenzen bei Datenabhängigkeiten und Fremdschlüsseleinschränkungen zu vermeiden. 🎜🎜🎜🎜Stoppen Sie MySQL vollständig und sichern Sie die Datenbankdateien. 🎜🎜🎜🎜Wenn Sie MySQL-Dump für die Sicherung verwenden, Sichern Sie die Binärprotokolldateien, um sicherzustellen, dass die Replikation nicht unterbrochen wird. 🎜🎜🎜🎜Vertrauen Sie nicht den LVM-Snapshots, die wahrscheinlich zu Dateninkonsistenzen führen, die Ihnen in Zukunft Probleme bereiten werden -Tabellenwiederherstellung einfacher, wenn die Daten von anderen Tabellen isoliert sind, werden die Daten in Tabelleneinheiten exportiert. 🎜🎜🎜🎜Bitte verwenden Sie <code>–opt</code>, wenn Sie <code>mysqldump</code> verwenden; 🎜🎜🎜🎜Tabellen vor dem Backup prüfen und optimieren;🎜</li> <li><p>Für einen schnelleren Import werden Fremdschlüsseleinschränkungen und die Eindeutigkeitserkennung während des Imports vorübergehend deaktiviert. </p></li> <li> <p> Berechnen Sie die Größe der Datenbank, der Tabelle und des Index nach jeder Sicherung, um das Wachstum der Datengröße überwachen zu können </p>Führen Sie regelmäßige Backups durch. </li> <li> <p></p>42. Der Abfragepuffer verarbeitet Leerzeichen nicht automatisch. Daher sollten Sie beim Schreiben von SQL-Anweisungen versuchen, die Verwendung von Leerzeichen zu reduzieren, insbesondere die Leerzeichen am Anfang und Ende von SQL (da der Abfragecache dies nicht automatisch tut). die Leerzeichen am Anfang und am Ende abfangen). </li> </ul> <p>43. Kann ein Mitglied „mid“ als Standard verwenden, um die Tabelle zur einfachen Abfrage in Tabellen zu unterteilen? In allgemeinen Geschäftsanforderungen wird der Benutzername grundsätzlich als Abfragebasis verwendet. Normalerweise sollte der Benutzername als Hash-Modul zum Teilen von Tabellen verwendet werden. Was die Tabellenpartitionierung betrifft, so erledigt dies die MySQL-Funktion <code>partition</code> und ist für den Code transparent. Es erscheint unangemessen, sie auf Codeebene zu implementieren. <br></p>44. Wir sollten eine ID als Primärschlüssel für jede Tabelle in der Datenbank festlegen, am besten einen INT-Typ (<code>UNSIGNED</code> wird empfohlen) und ihn so einstellen, dass <code>AUTO_INCREMENT automatisch erhöht wird </code> Flag. <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. Setzen Sie <code>SET NOCOUNT ON</code> am Anfang aller gespeicherten Prozeduren und Trigger und <code>SET NOCOUNT OFF</code> am Ende. Es ist nicht erforderlich, nach jeder Anweisung gespeicherter Prozeduren und Trigger eine <code>DONE_IN_PROC</code>-Nachricht an den Client zu senden. </p> <p><br>46. MySQL-Abfragen können einen Hochgeschwindigkeits-Abfrage-Cache ermöglichen. Dies ist eine der effektivsten MySQL-Optimierungsmethoden zur Verbesserung der Datenbankleistung. Wenn dieselbe Abfrage mehrmals ausgeführt wird, ist es viel schneller, die Daten aus dem Cache abzurufen und direkt aus der Datenbank zurückzugeben. </p> <p></p>47. Die <code>EXPLAIN SELECT</code>-Abfrage wird verwendet, um den Anzeigeeffekt zu verfolgen: <p><a href="https://www.php.cn/mysql-tutorials.html" target="_self"></a>Mit dem Schlüsselwort EXPLAIN erfahren Sie, wie MySQL Ihre SQL-Anweisung verarbeitet. Dies kann Ihnen bei der Analyse der Leistungsengpässe Ihrer Abfrageanweisungen oder Tabellenstrukturen helfen. Die Ergebnisse der EXPLAIN-Abfrage zeigen Ihnen auch, wie Ihre Indexprimärschlüssel verwendet werden und wie Ihre Datentabellen durchsucht und sortiert werden. </p>🎜🎜48. Verwenden Sie LIMIT 1, wenn nur eine Datenzeile vorhanden ist: 🎜🎜🎜Manchmal wissen Sie beim Abfragen der Tabelle bereits, dass das Ergebnis nur ein Ergebnis sein wird, aber weil Sie möglicherweise den Cursor abrufen müssen, oder Sie können die Anzahl der zurückgegebenen Datensätze überprüfen. In diesem Fall kann das Hinzufügen von <code>LIMIT 1 </code> die Leistung steigern. Auf diese Weise stoppt die MySQL-Datenbank-Engine die Suche, nachdem sie ein Datenelement gefunden hat, anstatt weiter nach dem nächsten Datenelement zu suchen, das mit dem Datensatz übereinstimmt. 🎜🎜49. Wählen Sie eine geeignete Speicher-Engine für die Tabelle: 🎜🎜🎜<strong>myisam:</strong> Die Anwendung basiert hauptsächlich auf Lese- und Einfügevorgängen, mit nur wenigen Aktualisierungen und Löschungen und der Integrität und Die Parallelitätsanforderungen der Transaktion sind nicht sehr hoch. 🎜🎜🎜<strong>InnoDB:</strong> Transaktionsverarbeitung und Datenkonsistenz unter gleichzeitigen Bedingungen erforderlich. Neben Einfügungen und Abfragen umfasst es auch viele Aktualisierungen und Löschungen. (InnoDB reduziert effektiv Sperren, die durch Löschungen und Aktualisierungen verursacht werden). 🎜🎜Bei Tabellen vom Typ InnoDB, die Transaktionen unterstützen, besteht der Hauptgrund, der sich auf die Geschwindigkeit auswirkt, darin, dass die Standardeinstellung von <code>AUTOCOMMIT</code> aktiviert ist und das Programm BEGIN nicht explizit aufruft, um die Transaktion zu starten, was dazu führt Einfügen automatisch übermittelt werden, was die Geschwindigkeit erheblich beeinträchtigt. Sie können begin vor der Ausführung von SQL aufrufen (auch wenn Autocommit aktiviert ist), was die Leistung erheblich verbessert. 🎜🎜50. Optimieren Sie den Datentyp der Tabelle und wählen Sie den entsprechenden Datentyp: 🎜🎜🎜<strong>Prinzip:</strong> Kleiner ist normalerweise besser, einfach ist besser, alle Felder müssen Standardwerte haben und versuchen, dies zu vermeiden NULL. MySQL kann den Zugriff auf große Datenmengen sehr gut unterstützen, aber im Allgemeinen gilt: Je kleiner die Tabelle in der Datenbank, desto schneller werden die darauf ausgeführten Abfragen. Um eine bessere Leistung zu erzielen, können wir daher beim Erstellen einer Tabelle die Breite der Felder in der Tabelle so klein wie möglich einstellen. 🎜🎜Ebenso sollten wir, wenn möglich, <code>MEDIUMINT </code> anstelle von <code>BIGIN </code> verwenden, um Ganzzahlfelder zu definieren, und wir sollten versuchen, das Feld auf <code>NOT NULL</code>zu setzen >, damit die Datenbank beim Ausführen von Abfragen in Zukunft keine NULL-Werte mehr vergleichen muss. 🎜🎜Für einige Textfelder, wie zum Beispiel „Provinz“ oder „Geschlecht“, können wir sie als Typ <code>ENUM </code> definieren. Denn in MySQL wird der ENUM-Typ als numerische Daten behandelt und numerische Daten werden viel schneller verarbeitet als Texttypen. Auf diese Weise kann die Leistung der Datenbank verbessert werden. 🎜🎜🎜51. String-Datentypen: char, varchar, text. 🎜🎜🎜52. Jede Operation an Spalten führt zu einem Tabellenscan, der Datenbankfunktionen, Berechnungsausdrücke usw. umfasst. Verschieben Sie die Operation bei Abfragen so weit wie möglich auf die rechte Seite des Gleichheitszeichens. 🎜🎜Empfohlenes Tutorial: „🎜MySQL-Tutorial🎜“🎜
Verwandte Etiketten:
Quelle:ksbbs.com
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage