mysql官方文檔之WHERE子句優化

WHERE Clause Optimization(WHERE子句優化)

        This section discusses optimizations that can be made for processing WHERE clauses. The examples use SELECT statements, but the same optimizations apply for WHERE clauses in DELETE and UPDATE statements.
         本節討論可用於處理條款的WHERE子句優化。這些例子使用SELECT語句,但同樣的優化適用於DELETE和UPDATE語句中的WHERE子句。

        You might be tempted to rewrite your queries to make arithmetic operations faster, while sacrificing readability. Because MySQL does similar optimizations automatically, you can often avoid this work, and leave the query in a more understandable and maintainable form.

        您可能會嘗試以犧牲可讀性來重寫查詢,以便可以更快地進行算術運算。因爲MySQL會自動進行類似的優化,所以通常可以避免這種工作,並將查詢置於更易於理解和可維護的形式中。(意思是你自認爲的可以加快查詢速度的轉換優化其實是在多此一舉,mysql本身就已經爲我們做了這一份工作,而且你的多此一舉還讓查詢語句的的可讀性降低了,並且沒有產生任何效果)

        Some of the optimizations performed by MySQL follow:

        mysql執行的一些優化如下:

        Removal of unnecessary parentheses:(刪除不必要的括號)

((a AND b) AND c OR (((a AND b) AND (c AND d))))
-> (a AND b AND c) OR (a AND b AND c AND d)

        Constant folding:(常量合併)

(a<b AND b=c) AND a=5
-> b>5 AND b=c AND a=5

        Constant condition removal (needed because of constant folding):(持續條件移除;不斷的摺疊需要)

(B>=5 AND B=5) OR (B=6 AND 5=5) OR (B=7 AND 5=6)
-> B=5 OR B=6

        Constant expressions used by indexes are evaluated only once.(索引使用的常量表達式值評估一次)

        COUNT(*) on a single table without a WHERE is retrieved directly from the table information for MyISAM and MEMORY tables. This is also done for any NOT NULL expression when used with only one table.

        COUNT(*)在單個表上,沒有一個WHER條件,直接從MyISAM和MEMORY表的表信息中檢索。當只使用一張表時,對於任何NOT NULL表達式都可以這樣做。

        Early detection of invalid constant expressions. MySQL quickly detects that some SELECT statements are impossible and returns no rows.

        無效的常數表達式的早期檢測。MySQL很快就會發現一些SELECT語句是不可能的,並且返回沒有行。

        HAVING is merged with WHERE if you do not use GROUP BY or aggregate functions (COUNT(),

MIN(), and so on).

        如果您不使用GROUP BY或聚合函數(COUNT()、MIN()等等),則與WHERE條件合併。

for example:

select * from student where id>1 having age>16;
和
select * from student where id>1 and age>16;

這兩個是一個效果吧

        For each table in a join, a simpler WHERE is constructed to get a fast WHERE evaluation for the table

and also to skip rows as soon as possible.

        對於聯接中的每個表,構造一個更簡單的WHERE條件,以便快速地對錶的條件進行評估,並儘可能快地跳過行。(連接的時候join on 的列簡單)

        All constant tables are read first before any other tables in the query. A constant table is any of the following:

        在查詢任何其他表之前,首先讀取的是常量表;常量表可以是下面的任何一種:

        (1)An empty table or a table with one row.空的表或者只有一行的表

        (2)A table that is used with a WHERE clause on a PRIMARY KEY or a UNIQUE index, where all index parts are compared to constant expressions and are defined as NOT NULL.在主鍵或惟一索引上使用WHERE子句的表,其中所有索引部件都與常量表達式相比較,並被定義爲NOT NULL。

          All of the following tables are used as constant tables:(下面所有表都被用作常量表)

SELECT * FROM t WHERE primary_key=1;
SELECT * FROM t1,t2 WHERE t1.primary_key=1 AND t2.primary_key=t1.id;

        The best join combination for joining the tables is found by trying all possibilities. If all columns in ORDER BY and GROUP BY clauses come from the same table, that table is preferred first when joining.

        通過嘗試所有的可能性,可以找到連接表的最佳連接組合。如果按ORDER BY和GROUP BY子句的所有列都來自同一個表,那麼在連接時,該表優先考慮。

        If there is an ORDER BY clause and a different GROUP BY clause, or if the ORDER BY or GROUP BY contains columns from tables other than the first table in the join queue, a temporary table is created.

        如果有一個ORDER BY子句和一個不同的GROUP BY子句,或者如果ORDER BY或GROUP BY包含來自join隊列中的第一張表以外的表的列,那麼就會創建一個臨時表。(讓GROUP BY和ORDER BY的列所在的表放在join隊列的第一個位置)

        If you use the SQL_SMALL_RESULT modifier, MySQL uses an in-memory temporary table.

        如果您使用SQL_SMALL_RESULT 修飾符,MySQL使用一個內存中的臨時表。

        Each table index is queried, and the best index is used unless the optimizer believes that it is more efficient to use a table scan. At one time, a scan was used based on whether the best index spanned more than 30% of the table, but a fixed percentage no longer determines the choice between using an index or a scan. The optimizer now is more complex and bases its estimate on additional factors such as table size, number of rows, and I/O block size.

        每個表索引都被查詢,並且使用最好的索引,除非優化器認爲使用表掃描更有效。與此同時,一次掃描以最佳索引是否跨越了超過30%的表爲基礎,但是一個固定的百分比不再決定是否使用索引或表掃描之間的選擇。優化器現在更加複雜,並將其估計建立在其他因素上,如表大小、行數和輸入/輸出塊大小。

        In some cases, MySQL can read rows from the index without even consulting the data file. If all columns used from the index are numeric, only the index tree is used to resolve the query.

        在某些情況下,MySQL可以在不諮詢數據文件的情況下讀取索引中的行。如果從索引中使用的所有列都是數字,則只使用索引樹來解析查詢。

        Before each row is output, those that do not match the HAVING clause are skipped.

       在每一行輸出之前,跳過那些不匹配HAVING 從句的內容。

        Some examples of queries that are very fast:(一些查詢非常快的例子)

SELECT COUNT(*) FROM tbl_name;
SELECT MIN(key_part1),MAX(key_part1) FROM tbl_name;
SELECT MAX(key_part2) FROM tbl_name WHERE key_part1=constant;
SELECT ... FROM tbl_name ORDER BY key_part1,key_part2,... LIMIT 10;
SELECT ... FROM tbl_name ORDER BY key_part1 DESC, key_part2 DESC, ... LIMIT 10;

        MySQL resolves the following queries using only the index tree, assuming that the indexed columns are numeric:

        假設索引列是數字,MySQL只使用索引樹解決的查詢

SELECT key_part1,key_part2 FROM tbl_name WHERE key_part1=val;
SELECT COUNT(*) FROM tbl_name WHERE key_part1=val1 AND key_part2=val2;
SELECT key_part2 FROM tbl_name GROUP BY key_part1;

        The following queries use indexing to retrieve the rows in sorted order without a separate sorting pass:

        下面的查詢使用索引來檢索排序順序中的行,而不需要單獨的排序:

SELECT ... FROM tbl_name ORDER BY key_part1,key_part2,... ;
SELECT ... FROM tbl_name ORDER BY key_part1 DESC, key_part2 DESC, ... ;

        非常感謝查看文章的同學指正錯誤,提供意見。

        上一篇:https://blog.csdn.net/qwerdf10010/article/details/80491722

        下一篇:https://blog.csdn.net/qwerdf10010/article/details/80515872

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章