MySQL 8.0 Reference Manual(讀書筆記59節--Controlling the Query Optimizer(2))

来源:https://www.cnblogs.com/xuliuzai/p/18216827
-Advertisement-
Play Games

MySQL語句優化包括創建合適的索引、使用覆蓋索引、避免不必要的子查詢、通過 EXPLAIN 分析查詢計劃、進行批量操作、減少鎖定範圍、使用預編譯語句和查詢緩存,以顯著提高查詢性能和資料庫運行效率。 ...


3.2 Optimizer Hint Syntax

Optimizer hints must be specified within /*+ ... */ comments. That is, optimizer hints use a variant of /* ... */ C-style comment syntax, with a + character following the /* comment opening sequence. Examples:

/*+ BKA(t1) */
/*+ BNL(t1, t2) */
/*+ NO_RANGE_OPTIMIZATION(t4 PRIMARY) */
/*+ QB_NAME(qb2) */

Whitespace【空白符;空白字元;空格;白空格;白空間;】 is permitted after the + character.

The parser recognizes optimizer hint comments after the initial keyword of SELECT, UPDATE, INSERT, REPLACE, and DELETE statements. Hints are permitted in these contexts:

• At the beginning of query and data change statements:

SELECT /*+ ... */ ...
INSERT /*+ ... */ ...
REPLACE /*+ ... */ ...
UPDATE /*+ ... */ ...
DELETE /*+ ... */ ...

• At the beginning of query blocks:

(SELECT /*+ ... */ ... )
(SELECT ... ) UNION (SELECT /*+ ... */ ... )
(SELECT /*+ ... */ ... ) UNION (SELECT /*+ ... */ ... )
UPDATE ... WHERE x IN (SELECT /*+ ... */ ...)
INSERT ... SELECT /*+ ... */ ...

• In hintable statements prefaced by EXPLAIN. For example:

EXPLAIN SELECT /*+ ... */ ...
EXPLAIN UPDATE ... WHERE x IN (SELECT /*+ ... */ ...)

   The implication is that you can use EXPLAIN to see how optimizer hints affect execution plans. Use SHOW WARNINGS immediately after EXPLAIN to see how hints are used. The extended EXPLAIN output displayed by a following SHOW WARNINGS indicates which hints were used. Ignored hints are not displayed.

A hint comment may contain multiple hints, but a query block cannot contain multiple hint comments. This is valid【ˈvælɪd (法律上)有效的;合理的;(正式)認可的;有根據的;確鑿的;符合邏輯的;系統認可的;】:

SELECT /*+ BNL(t1) BKA(t2) */ ...

But this is invalid【ɪnˈvælɪd , ˈɪnvəlɪd 無效的;(法律上或官方)不承認的;站不住腳的;不能識別的;無充分事實的;】:

SELECT /*+ BNL(t1) */ /* BKA(t2) */ ...

When a hint comment contains multiple hints, the possibility of duplicates and conflicts exists. The following general guidelines apply. For specific hint types, additional rules may apply, as indicated in the hint descriptions.

• Duplicate hints: For a hint such as /*+ MRR(idx1) MRR(idx1) */, MySQL uses the first hint and issues a warning about the duplicate hint.

• Conflicting hints: For a hint such as /*+ MRR(idx1) NO_MRR(idx1) */, MySQL uses the first hint and issues a warning about the second conflicting hint.

Query block names are identifiers and follow the usual rules about what names are valid and how to quote【kwoʊt 引用;】 them.

Hint names, query block names, and strategy names are not case-sensitive. References to table and index names follow the usual identifier case-sensitivity rules.

3.3 Join-Order Optimizer Hints

Join-order hints affect the order in which the optimizer joins tables.

Syntax of the JOIN_FIXED_ORDER hint:

hint_name([@query_block_name])

Syntax of other join-order hints:

hint_name([@query_block_name] tbl_name [, tbl_name] ...)
hint_name(tbl_name[@query_block_name] [, tbl_name[@query_block_name]] ...)

The syntax refers to these terms:

 • hint_name: These hint names are permitted:

  • JOIN_FIXED_ORDER: Force the optimizer to join tables using the order in which they appear in the FROM clause. This is the same as specifying SELECT STRAIGHT_JOIN.
  • JOIN_ORDER: Instruct the optimizer to join tables using the specified table order. The hint applies to the named tables. The optimizer may place tables that are not named anywhere in the join order, including between specified tables.
  • JOIN_PREFIX: Instruct the optimizer to join tables using the specified table order for the first tables of the join execution plan. The hint applies to the named tables. The optimizer places all other tables after the named tables.
  • JOIN_SUFFIX: Instruct the optimizer to join tables using the specified table order for the last tables of the join execution plan. The hint applies to the named tables. The optimizer places all other tables before the named tables.

• tbl_name: The name of a table used in the statement. A hint that names tables applies to all tables that it names. The JOIN_FIXED_ORDER hint names no tables and applies to all tables in the FROM clause of the query block in which it occurs.

If a table has an alias, hints must refer to the alias, not the table name.

Table names in hints cannot be qualified with schema names.

• query_block_name: The query block to which the hint applies. If the hint includes no leading @query_block_name, the hint applies to the query block in which it occurs. For tbl_name@query_block_name syntax, the hint applies to the named table in the named query block.

Example:

SELECT
/*+ JOIN_PREFIX(t2, t5@subq2, t4@subq1)
 JOIN_ORDER(t4@subq1, t3)
 JOIN_SUFFIX(t1) */
COUNT(*) FROM t1 JOIN t2 JOIN t3
 WHERE t1.f1 IN (SELECT /*+ QB_NAME(subq1) */ f1 FROM t4)
 AND t2.f1 IN (SELECT /*+ QB_NAME(subq2) */ f1 FROM t5);

Hints control the behavior of semijoin tables that are merged to the outer query block. If subqueries subq1 and subq2 are converted to semijoins, tables t4@subq1 and t5@subq2 are merged to the outer query block. In this case, the hint specified in the outer query block controls the behavior of t4@subq1, t5@subq2 tables.

The optimizer resolves join-order hints according to these principles:

• Multiple hint instances

Only one JOIN_PREFIX and JOIN_SUFFIX hint of each type are applied. Any later hints of the same type are ignored with a warning. JOIN_ORDER can be specified several times.

Examples:

/*+ JOIN_PREFIX(t1) JOIN_PREFIX(t2) */

The second JOIN_PREFIX hint is ignored with a warning.

/*+ JOIN_PREFIX(t1) JOIN_SUFFIX(t2) */

Both hints are applicable. No warning occurs.

/*+ JOIN_ORDER(t1, t2) JOIN_ORDER(t2, t3) */

Both hints are applicable. No warning occurs.

• Conflicting hints

In some cases hints can conflict, such as when JOIN_ORDER and JOIN_PREFIX have table orders that are impossible to apply at the same time:

SELECT /*+ JOIN_ORDER(t1, t2) JOIN_PREFIX(t2, t1) */ ... FROM t1, t2;

In this case, the first specified hint is applied and subsequent conflicting hints are ignored with no warning. A valid hint that is impossible to apply is silently ignored with no warning.

• Ignored hints

A hint is ignored if a table specified in the hint has a circular【ˈsɜːrkjələr 圓形的;圓的;環形的;環行的;繞圈的;迴圈論證的(以一種觀點證明另一觀點,接著再用後一種觀點反過來去證明前一觀點);大量送發的;】 dependency.

Example:

/*+ JOIN_ORDER(t1, t2) JOIN_PREFIX(t2, t1) */

The JOIN_ORDER hint sets table t2 dependent on t1. The JOIN_PREFIX hint is ignored because table t1 cannot be dependent on t2. Ignored hints are not displayed in extended EXPLAIN output.

• Interaction with const tables

The MySQL optimizer places const tables first in the join order, and the position of a const table cannot be affected by hints. References to const tables in join-order hints are ignored, although the hint is still applicable. For example, these are equivalent:

JOIN_ORDER(t1, const_tbl, t2)
JOIN_ORDER(t1, t2)

Accepted hints shown in extended EXPLAIN output include const tables as they were specified.

• Interaction with types of join operations

MySQL supports several type of joins: LEFT, RIGHT, INNER, CROSS, STRAIGHT_JOIN. A hint that conflicts with the specified type of join is ignored with no warning.

Example:

SELECT /*+ JOIN_PREFIX(t1, t2) */FROM t2 LEFT JOIN t1;

Here a conflict occurs between the requested join order in the hint and the order required by the LEFT JOIN. The hint is ignored with no warning.

3.4 Table-Level Optimizer Hints

Table-level hints affect:

• Use of the Block Nested-Loop (BNL) and Batched Key Access (BKA) join-processing algorithms.

• Whether derived tables, view references, or common table expressions should be merged into the outer query block, or materialized using an internal temporary table.

• Use of the derived table condition pushdown optimization (added in MySQL 8.0.22).

These hint types apply to specific tables, or all tables in a query block.

Syntax of table-level hints:

hint_name([@query_block_name] [tbl_name [, tbl_name] ...])
hint_name([tbl_name@query_block_name [, tbl_name@query_block_name] ...])

The syntax refers to these terms:

• hint_name: These hint names are permitted:

  • BKA, NO_BKA: Enable or disable batched key access for the specified tables.
  • BNL, NO_BNL: Enable or disable block nested loop for the specified tables. In MySQL 8.0.18 and later, these hints also enable and disable the hash join optimization.
  • DERIVED_CONDITION_PUSHDOWN, NO_DERIVED_CONDITION_PUSHDOWN: Enable or disable use of derived table condition pushdown for the specified tables (added in MySQL 8.0.22).
  • HASH_JOIN, NO_HASH_JOIN: In MySQL 8.0.18 only, enable or disable use of a hash join for the specified tables. These hints have no effect in MySQL 8.0.19 or later, where you should use BNL or NO_BNL instead.
  • MERGE, NO_MERGE: Enable merging for the specified tables, view references or common table expressions; or disable merging and use materialization instead.

   【The block-nested loop optimization is removed in MySQL 8.0.20 and later releases, but BNL and NO_BNL continue to be supported for enabling and disabling hash joins.】

   【To use a block nested loop or batched key access hint to enable join buffering for any inner table of an outer join, join buffering must be enabled for all inner tables of the outer join.】

• tbl_name: The name of a table used in the statement. The hint applies to all tables that it names. If the hint names no tables, it applies to all tables of the query block in which it occurs.

If a table has an alias, hints must refer to the alias, not the table name.

Table names in hints cannot be qualified with schema names.

• query_block_name: The query block to which the hint applies. If the hint includes no leading @query_block_name, the hint applies to the query block in which it occurs. For tbl_name@query_block_name syntax, the hint applies to the named table in the named query block.

Examples:

SELECT /*+ NO_BKA(t1, t2) */ t1.* FROM t1 INNER JOIN t2 INNER JOIN t3;
SELECT /*+ NO_BNL() BKA(t1) */ t1.* FROM t1 INNER JOIN t2 INNER JOIN t3;
SELECT /*+ NO_MERGE(dt) */ * FROM (SELECT * FROM t1) AS dt;

A table-level hint applies to tables that receive records from previous tables, not sender tables. Consider this statement:

SELECT /*+ BNL(t2) */ FROM t1, t2;

If the optimizer chooses to process t1 first, it applies a Block Nested-Loop join to t2 by buffering the rows from t1 before starting to read from t2. If the optimizer instead chooses to process t2 first, the hint has no effect because t2 is a sender table.

For the MERGE and NO_MERGE hints, these precedence【ˈpresɪdəns 優先;優先權;】 rules apply:

• A hint takes precedence over any optimizer heuristic【hjuˈrɪstɪk (教學或教育)啟髮式的;】 that is not a technical constraint. (If providing a hint as a suggestion has no effect, the optimizer has a reason for ignoring it.)

• A hint takes precedence over the derived_merge flag of the optimizer_switch system variable.

• For view references, an ALGORITHM={MERGE|TEMPTABLE} clause in the view definition takes precedence over a hint specified in the query referencing the view.

3.5 Index-Level Optimizer Hints

Index-level hints affect which index-processing strategies the optimizer uses for particular tables or indexes. These hint types affect use of Index Condition Pushdown (ICP), Multi-Range Read (MRR), Index Merge, and range optimizations.

Syntax of index-level hints:

hint_name([@query_block_name] tbl_name [index_name [, index_name] ...])
hint_name(tbl_name@query_block_name [index_name [, index_name] ...])

The syntax refers to these terms:

• hint_name: These hint names are permitted:

  • GROUP_INDEX, NO_GROUP_INDEX: Enable or disable the specified index or indexes for index scans for GROUP BY operations. Equivalent to the index hints FORCE INDEX FOR GROUP BY, IGNORE INDEX FOR GROUP BY. Available in MySQL 8.0.20 and later.
  • INDEX, NO_INDEX: Acts as the combination of JOIN_INDEX, GROUP_INDEX, and ORDER_INDEX, forcing the server to use the specified index or indexes for any and all scopes, or as the combination of NO_JOIN_INDEX, NO_GROUP_INDEX, and NO_ORDER_INDEX, which causes the server to ignore the specified index or indexes for any and all scopes. Equivalent to FORCE INDEX, IGNORE INDEX. Available beginning with MySQL 8.0.20.
  • INDEX_MERGE, NO_INDEX_MERGE: Enable or disable the Index Merge access method for the specified table or indexes.These hints apply to all three Index Merge algorithms.The INDEX_MERGE hint forces the optimizer to use Index Merge for the specified table using the specified set of indexes. If no index is specified, the optimizer considers all possible index combinations and selects the least expensive one. The hint may be ignored if the index combination is inapplicable to the given statement. The NO_INDEX_MERGE hint disables Index Merge combinations that involve any of the specified indexes. If the hint specifies no indexes, Index Merge is not permitted for the table.
  • JOIN_INDEX, NO_JOIN_INDEX: Forces MySQL to use or ignore the specified index or indexes for any access method, such as ref, range, index_merge, and so on. Equivalent to FORCE INDEX FOR JOIN, IGNORE INDEX FOR JOIN. Available in MySQL 8.0.20 and later.
  • MRR, NO_MRR: Enable or disable MRR for the specified table or indexes. MRR hints apply only to InnoDB and MyISAM tables.
  • NO_ICP: Disable ICP for the specified table or indexes. By default, ICP is a candidate optimization strategy, so there is no hint for enabling it.
  • NO_RANGE_OPTIMIZATION: Disable index range access for the specified table or indexes. This hint also disables Index Merge and Loose Index Scan for the table or indexes. By default, range access is a candidate optimization strategy, so there is no hint for enabling it. This hint may be useful when the number of ranges may be high and range optimization would require many resources.
  • ORDER_INDEX, NO_ORDER_INDEX: Cause MySQL to use or to ignore the specified index or indexes for sorting rows. Equivalent to FORCE INDEX FOR ORDER BY, IGNORE INDEX FOR ORDER BY. Available beginning with MySQL 8.0.20.
  • SKIP_SCAN, NO_SKIP_SCAN: Enable or disable the Skip Scan access method for the specified table or indexes. These hints are available as of MySQL 8.0.13. The SKIP_SCAN hint forces the optimizer to use Skip Scan for the specified table using the specified set of indexes. If no index is specified, the optimizer considers all possible indexes and selects the least expensive one. The hint may be ignored if the index is inapplicable to the given statement. The NO_SKIP_SCAN hint disables Skip Scan for the specified indexes. If the hint specifies no indexes, Skip Scan is not permitted for the table.

• tbl_name: The table to which the hint applies.

• index_name: The name of an index in the named table. The hint applies to all indexes that it names. If the hint names no indexes, it applies to all indexes in the table.

To refer to a primary key, use the name PRIMARY. To see the index names for a table, use SHOW INDEX.

• query_block_name: The query block to which the hint applies. If the hint includes no leading @query_block_name, the hint applies to the query block in which it occurs. For tbl_name@query_block_name syntax, the hint applies to the named table in the named query block.

Examples:

SELECT /*+ INDEX_MERGE(t1 f3, PRIMARY) */ f2 FROM t1
 WHERE f1 = 'o' AND f2 = f3 AND f3 <= 4;
SELECT /*+ MRR(t1) */ * FROM t1 WHERE f2 <= 3 AND 3 <= f3;
SELECT /*+ NO_RANGE_OPTIMIZATION(t3 PRIMARY, f2_idx) */ f1
 FROM t3 WHERE f1 > 30 AND f1 < 33;
INSERT INTO t3(f1, f2, f3)
 (SELECT /*+ NO_ICP(t2) */ t2.f1, t2.f2, t2.f3 FROM t1,t2
 WHERE t1.f1=t2.f1 AND t2.f2 BETWEEN t1.f1
 AND t1.f2 AND t2.f2 + 1 >= t1.f1 + 1);
SELECT /*+ SKIP_SCAN(t1 PRIMARY) */ f1, f2
 FROM t1 WHERE f2 > 40;

The following examples use the Index Merge hints, but other index-level hints follow the same principles regarding hint ignoring and precedence of optimizer hints in relation to the optimizer_switch system variable or index hints.

Assume that table t1 has columns a, b, c, and d; and that indexes named i_a, i_b, and i_c exist on a, b, and c, respectively:

SELECT /*+ INDEX_MERGE(t1 i_a, i_b, i_c)*/ * FROM t1
 WHERE a = 1 AND b = 2 AND c = 3 AND d = 4;

Index Merge is used for (i_a, i_b, i_c) in this case.

SELECT /*+ INDEX_MERGE(t1 i_a, i_b, i_c)*/ * FROM t1
 WHERE b = 1 AND c = 2 AND d = 3;

Index Merge is used for (i_b, i_c) in this case.

/*+ INDEX_MERGE(t1 i_a, i_b) NO_INDEX_MERGE(t1 i_b) */

NO_INDEX_MERGE is ignored because there is a preceding hint for the same table.

/*+ NO_INDEX_MERGE(t1 i_a, i_b) INDEX_MERGE(t1 i_b) */

INDEX_MERGE is ignored because there is a preceding hint for the same table.

For the INDEX_MERGE and NO_INDEX_MERGE optimizer hints, these precedence rules apply:

• If an optimizer hint is specified and is applicable, it takes precedence over the Index Merge-related flags of the optimizer_switch system variable.

SET optimizer_switch='index_merge_intersection=off';
SELECT /*+ INDEX_MERGE(t1 i_b, i_c) */ * FROM t1
WHERE b = 1 AND c = 2 AND d = 3;

The hint takes precedence over optimizer_switch. Index Merge is used for (i_b, i_c) in this case.

SET optimizer_switch='index_merge_intersection=on';
SELECT /*+ INDEX_MERGE(t1 i_b) */ * FROM t1
WHERE b = 1 AND c = 2 AND d = 3;

The hint specifies only one index, so it is inapplicable, and the optimizer_switch flag (on) applies. Index Merge is used if the optimizer assesses it to be cost efficient.

SET optimizer_switch='index_merge_intersection=off';
SELECT /*+ INDEX_MERGE(t1 i_b) */ * FROM t1
WHERE b = 1 AND c = 2 AND d = 3;

The hint specifies only one index, so it is inapplicable, and the optimizer_switch flag (off) applies. Index Merge is not used.

• The index-level optimizer hints GROUP_INDEX, INDEX, JOIN_INDEX, and ORDER_INDEX all take precedence over the equivalent FORCE INDEX hints; that is, they cause the FORCE INDEX hints to be ignored. Likewise, the NO_GROUP_INDEX, NO_INDEX, NO_JOIN_INDEX, and NO_ORDER_INDEX hints all take precedence over any IGNORE INDEX equivalents, also causing them to be ignored.

The index-level optimizer hints GROUP_INDEX, NO_GROUP_INDEX, INDEX,NO_INDEX, JOIN_INDEX,NO_JOIN_INDEX, ORDER_INDEX, and NO_ORDER_INDEX hints all take precedence over all other optimizer hints, including other index-level optimizer hints. Any other optimizer hints are applied only to the indexes permitted by these.

The GROUP_INDEX, INDEX, JOIN_INDEX, and ORDER_INDEX hints are all equivalent to FORCE INDEX and not to USE INDEX. This is because using one or more of these hints means that a table scan is used only if there is no way to use one of the named indexes to find rows in the table. To cause MySQL to use the same index or set of indexes as with a given instance of USE INDEX, you can use NO_INDEX, NO_JOIN_INDEX, NO_GROUP_INDEX, NO_ORDER_INDEX, or some combination of these.

To replicate the effect that USE INDEX has in the query SELECT a,c FROM t1 USE INDEX FOR ORDER BY (i_a) ORDER BY a, you can use the NO_ORDER_INDEX optimizer hint to cover all indexes on the table except the one that is desired like this:

SELECT /*+ NO_ORDER_INDEX(t1 i_b,i_c) */ a,c
 FROM t1
 ORDER BY a;

Attempting to combine NO_ORDER_INDEX for the table as a whole with USE INDEX FOR ORDER BY does not work to do this, because NO_ORDER_BY causes USE INDEX to be ignored, as shown here:

mysql> EXPLAIN SELECT /*+ NO_ORDER_INDEX(t1) */ a,c FROM t1
 -> USE INDEX FOR ORDER BY (i_a) ORDER BY a\G
*************************** 1. row ***************************
 id: 1
 select_type: SIMPLE
 table: t1
 partitions: NULL
 type: ALL
possible_keys: NULL
 key: NULL
 key_len: NULL
 ref: NULL
 rows: 256
 filtered: 100.00
 Extra: Using filesort

• The USE INDEX, FORCE INDEX, and IGNORE INDEX index hints have higher priority than the INDEX_MERGE and NO_INDEX_MERGE optimizer hints.

/*+ INDEX_MERGE(t1 i_a, i_b, i_c) */ ... IGNORE INDEX i_a

IGNORE INDEX takes precedence over INDEX_MERGE, so index i_a is excluded from the possible ranges for Index Merge.

/*+ NO_INDEX_MERGE(t1 i_a, i_b) */ ... FORCE INDEX i_a, i_b

Index Merge is disallowed for i_a, i_b because of FORCE INDEX, but the optimizer is forced to use either i_a or i_b for range or ref access. There are no conflicts; both hints are applicable.

• If an IGNORE INDEX hint names multiple indexes, those indexes are unavailable for Index Merge.

• The FORCE INDEX and USE INDEX hints make only the named indexes to be available for Index Merge.

SELECT /*+ INDEX_MERGE(t1 i_a, i_b, i_c) */ a FROM t1
FORCE INDEX (i_a, i_b) WHERE c = 'h' AND a = 2 AND b = 'b';

The Index Merge intersection access algorithm is used for (i_a, i_b). The same is true if FORCE INDEX is changed to USE INDEX.

3.6 Subquery Optimizer Hints

Subquery hints affect whether to use semijoin transformations and which semijoin strategies to permit, and, when semijoins are not used, whether to use subquery materialization or IN-to-EXISTS transformations【ˌtrænsfərˈmeɪʃənz (徹底的)變化,改觀,轉變,改革;(用於南非)民主改革;】.

Syntax【ˈsɪntæks 句法;句法規則;語構;】 of hints that affect semijoin strategies:

hint_name([@query_block_name] [strategy [, strategy] ...])

• hint_name: These hint names are permitted:

   • SEMIJOIN, NO_SEMIJOIN: Enable or disable the named semijoin strategies.

• strategy: A semijoin strategy to be enabled or disabled. These strategy names are permitted: DUPSWEEDOUT, FIRSTMATCH, LOOSESCAN, MATERIALIZATION.

For SEMIJOIN hints, if no strategies are named, semijoin is used if possible based on the strategies enabled according to the optimizer_switch system variable. If strategies are named but inapplicable for the statement, DUPSWEEDOUT is used.

For NO_SEMIJOIN hints, if no strategies are named, semijoin is not used. If strategies are named that rule out【rule out 排除;使成為不可能;阻止…發生;確定…不可能(或不合適);】 all applicable strategies for the statement, DUPSWEEDOUT is used.

If one subquery is nested within another and both are merged into a semijoin of an outer query, any specification of semijoin strategies for the innermost query are ignored. SEMIJOIN and NO_SEMIJOIN hints can still be used to enable or disable semijoin transformations for such nested subqueries.

If DUPSWEEDOUT is disabled, on occasion the optimizer may generate a query plan that is far from optimal. This occurs due to heuristic【hjuˈrɪstɪk (教學或教育)啟髮式的;】 pruning during greed【ˈɡriːdi 貪婪的;貪心的;貪吃的;渴望的;】y search, which can be avoided by setting optimizer_prune_level=0.

Examples:

SELECT /*+ NO_SEMIJOIN(@subq1 FIRSTMATCH, LOOSESCAN) */ * FROM t2
 WHERE t2.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3);
SELECT /*+ SEMIJOIN(@subq1 MATERIALIZATION, DUPSWEEDOUT) */ * FROM t2
 WHERE t2.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3);

Syntax of hints that affect whether to use subquery materialization or IN-to-EXISTS transformations:

SUBQUERY([@query_block_name] strategy)

The hint name is always SUBQUERY.

For SUBQUERY hints, these strategy values are permitted: INTOEXISTS, MATERIALIZATION.

Examples:

SELECT id, a IN (SELECT /*+ SUBQUERY(MATERIALIZATION) */ a FROM t1) FROM t2;
SELECT * FROM t2 WHERE t2.a IN (SELECT /*+ SUBQUERY(INTOEXISTS) */ a FROM t1);

For semijoin and SUBQUERY hints, a leading @query_block_name specifies the query block to which the hint applies. If the hint includes no leading @query_block_name, the hint applies to the query block in which it occurs.

If a hint comment contains multiple subquery hints, the first is used. If there are other following hints of that type, they produce a warning. Following hints of other types are silently ignored.


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 本文測試環境為SQLserver2019 背景 某業務流水錶,會基於固定範圍內的業務編號做寫入以及查詢操作,熱數據的量級在億級別,一個典型的查詢是基於業務編碼查詢最新(時間戳)某種狀態的前N條數據 簡化後的表結構如下 create table TestTable01 ( id bigint iden ...
  • 資料庫引入LLVM之後,可以為具體的查詢生成定製化的機器碼,並儘可能地將數據存儲在CPU的寄存器中進一步加快計算的速度。 ...
  • Redis事務與MySQL事務 不一樣。 原子性:MySQL有Undo Log機制,支持強原子性,和回滾。Redis只能保證事務內指令可以不被干擾的在同一批次執行,且沒有機制保證全部成功則提交,部分失敗則回滾。 隔離性:MySQL的隔離性指多個事務可以併發執行,MySQL有MVCC機制。而Redis ...
  • MySQL死鎖接觸少,但面試又經常被問到怎麼辦? 最近有小伙伴在面試的時候,被問了MySQL死鎖,如何解決? 雖然也回答出來了,但是不夠全面體系化, 所以,小北給大家做一下系統化、體系化的梳理,幫助大家在面試過程中能夠脫穎而出,拿到自己心儀的Offer 插播一條:如果你近期準備面試跳槽,建議在htt ...
  • 隨著大數據技術和人工智慧的發展,企業逐漸意識到構建一個集中化的指標管理平臺的必要性。這樣的平臺旨在解決幾個核心問題:首先,確保所有部門都能通過統一的入口提交指標需求,實現需求的透明化管理;其次,建立完善的指標管理體系,涵蓋從需求定義、模型設計、數據集成、開發實施到應用監控的全鏈條;第三,通過自動化和 ...
  • 如何對MySQL中的資料庫進行優化,如何優化數據表中的數據類型、刪除重覆、冗餘索引;如何設計資料庫,資料庫的範式要求。如何對數據表進行分析、檢查、優化、拆分。 ...
  • 在當今的互聯網時代,隨著用戶數量和請求量的不斷增加,系統的性能和穩定性面臨著巨大的挑戰。限流演算法作為保障系統穩定性的重要手段之一,被廣泛應用於各種服務和應用中。限流的核心目的是對某一時間視窗內的請求數進行限制,保持系統的可用性和穩定性,防止因流量暴增而導致的系統運行緩慢或宕機。 常見限流演算法對比 常 ...
  • 【標題】ODBC驅動類問題定位方法 【需求分類】故障分析 【關鍵字】ODBC 【需求描述】由於我們的ODBC介面目前尚不完善,經常會遇見ODBC介面能力不足導致應用功能無法運行的問題,需要定位手段確定底層是哪個介面報錯 【需求原因分析】方便一線資料庫管理員初步分析故障 【分析方法】 ● 由於我們的O ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...