Skip to content

Commit c329c43

Browse files
Olernovvuvova
authored andcommitted
MDEV-35856: implement index hints
Part of an umbrella task MDEV-33281 for implementing optimizer hints. This commit introduces hints affecting the use of indexes: - JOIN_INDEX, NO_JOIN_INDEX - GROUP_INDEX, NO_GROUP_INDEX - ORDER_INDEX, NO_ORDER_INDEX - INDEX, NO_INDEX Syntax of index hints: hint_name([@query_block_name] tbl_name [index_name [, index_name] ...]) hint_name(tbl_name@query_block_name [index_name [, index_name] ...]) JOIN_INDEX, NO_JOIN_INDEX: Forces the server 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. 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. ORDER_INDEX, NO_ORDER_INDEX: Causes the server 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. 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. Two kinds of index hints were introduced during implementation: the global kind for [NO_]INDEX hint, and the non-global kind for all others. Possible conflicts which will generate warnings: - for a table level hint - a hint of the same type or the opposite kind has already been specified for the same table - for a index level hint - the same type of hint has already been specified for the same table or for the same index, OR - the opposite kind of hint has already been specified for the same index - For a multi index hint like JOIN_INDEX(t1 i1, i2, i3), it conflicts with a previous hint if any of the JOIN_INDEX(t1 i1), JOIN_INDEX(t1 i2), JOIN_INDEX(t1 i3) conflicts with a previous hint
1 parent 4453d17 commit c329c43

File tree

11 files changed

+1121
-82
lines changed

11 files changed

+1121
-82
lines changed

mysql-test/main/opt_hints.result

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ a
2121
1
2222
2
2323
Warnings:
24-
Warning 4219 Hint NO_MRR(`t1` `idx_A`) is ignored as conflicting/duplicated
24+
Warning 4239 Hint NO_MRR(`t1` `idx_A`) is ignored as conflicting/duplicated (an index hint of the same type has already been specified for this key)
2525
Warning 4222 Unresolved index name `t1`@`select#1` `idx_å` for NO_MRR hint
2626
DROP TABLE t1;
2727
# Testing that query block names are accent sensitive case insensitive
@@ -885,7 +885,7 @@ Warning 4219 Hint BKA(`t1`@`q1`) is ignored as conflicting/duplicated
885885
SELECT /*+ QB_NAME(q1) NO_ICP(@q1 t1 PRIMARY) NO_ICP(@q1 t1 PRIMARY) */ * FROM t1;
886886
i
887887
Warnings:
888-
Warning 4219 Hint NO_ICP(`t1`@`q1` `PRIMARY`) is ignored as conflicting/duplicated
888+
Warning 4239 Hint NO_ICP(`t1`@`q1` `PRIMARY`) is ignored as conflicting/duplicated (an index hint of the same type has already been specified for this key)
889889
DROP TABLE t1;
890890
#
891891
# Hints inside views are not supported

mysql-test/main/opt_hints_index.result

Lines changed: 274 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
--enable_prepare_warnings
2+
--disable_view_protocol # Since optimizer hints are not supported inside views
3+
4+
CREATE TABLE t1 (a INT, b INT, c INT, d INT,
5+
KEY i_a(a), KEY i_b(b),
6+
KEY i_ab(a,b), KEY i_c(c), KEY i_d(d));
7+
INSERT INTO t1 VALUES
8+
(1,1,1,1),(2,2,2,1),(3,3,3,1),(4,4,4,1),
9+
(5,5,5,1),(6,6,6,1),(7,7,7,1),(8,8,8,1);
10+
INSERT INTO t1 SELECT a,b, c + 10, d FROM t1;
11+
INSERT INTO t1 SELECT a,b, c + 20, d FROM t1;
12+
INSERT INTO t1 SELECT a,b, c + 40, d FROM t1;
13+
INSERT INTO t1 SELECT a,b, c + 80, d FROM t1;
14+
INSERT INTO t1 SELECT a,b, c + 160, d FROM t1;
15+
ANALYZE TABLE t1;
16+
17+
--echo # Check behavior of duplicated/intersected hints.
18+
--echo # First specified hint is applied and next conflicting/intersected hints
19+
--echo # are ignored with warning.
20+
21+
--echo # JOIN_INDEX(t1) is ignored as intersected (INDEX/other hint for the same table)
22+
EXPLAIN EXTENDED SELECT /*+ INDEX(t1) JOIN_INDEX(t1) */ a FROM t1;
23+
--echo # INDEX(t1 i_d) is ignored as duplicated (same type of hint for the same table)
24+
EXPLAIN EXTENDED SELECT /*+ INDEX(t1 i_a, i_b, i_c) NO_INDEX(t1 i_d) */ a FROM t1;
25+
--echo # JOIN_INDEX(t1 i_a, i_b) is ignored as intersected (INDEX/other hint for the same table)
26+
EXPLAIN EXTENDED SELECT /*+ INDEX(t1 i_a) JOIN_INDEX(t1 i_a, i_b) JOIN_INDEX(t1 i_b) */ a FROM t1;
27+
--echo # GROUP_INDEX(t1 i_a, i_b) is ignored as intersected (INDEX/other hint for the same table)
28+
EXPLAIN EXTENDED SELECT /*+ INDEX(t1 i_a) GROUP_INDEX(t1 i_a, i_b) GROUP_INDEX(t1 i_b) */ a FROM t1;
29+
--echo # GROUP_INDEX(t1) is ignored as intersected (INDEX/other hint for the same table)
30+
EXPLAIN EXTENDED SELECT /*+ INDEX(t1 i_a) GROUP_INDEX(t1) */ a FROM t1;
31+
--echo # ORDER_INDEX(t1 i_a, i_b) is ignored as intersected (INDEX/other hint for the same key)
32+
EXPLAIN EXTENDED SELECT /*+ INDEX(t1 i_a) ORDER_INDEX(t1 i_a, i_b) ORDER_INDEX(t1 i_b) */ a FROM t1;
33+
--echo # INDEX(t1 i_b,i_a) is ignored as intersected (INDEX/other hint for the same key)
34+
EXPLAIN EXTENDED SELECT /*+ ORDER_INDEX(t1 i_a) INDEX(t1 i_b,i_a)*/ a FROM t1;
35+
--echo # ORDER_INDEX(t1) is ignored as intersected (INDEX/other hint for the same table)
36+
EXPLAIN EXTENDED SELECT /*+ INDEX(t1 i_a) ORDER_INDEX(t1) */ a FROM t1;
37+
--echo # ORDER_INDEX(t1 i_b) is ignored as intersected (same hint/INDEX for the same table)
38+
EXPLAIN EXTENDED SELECT /*+ ORDER_INDEX(t1 i_a, i_b) NO_ORDER_INDEX(t1 i_b) INDEX(t1 i_c)*/ a FROM t1;
39+
--echo # INDEX(t1) is ignored as intersected (INDEX/other hint for the same table)
40+
EXPLAIN EXTENDED SELECT /*+ ORDER_INDEX(t1 i_a, i_b) GROUP_INDEX(t1 i_b) INDEX(t1)*/ a FROM t1;
41+
--echo # INDEX(t1) is ignored as intersected (INDEX/other hint for the same table)
42+
EXPLAIN EXTENDED SELECT /*+ ORDER_INDEX(t1) GROUP_INDEX(t1) INDEX(t1)*/ a FROM t1;
43+
--echo # Check the use of index hints.
44+
--echo # Force the use of i_a, i_b indexes, intersect(i_a,i_b) is used.
45+
EXPLAIN EXTENDED SELECT /*+ INDEX(t1 i_a, i_b) */ a FROM t1 WHERE a = 1 AND b = 2 AND c = 3;
46+
--echo # Force the use of i_a, i_ab indexes, i_ab index is used.
47+
EXPLAIN EXTENDED SELECT /*+ INDEX(t1 i_a, i_ab) */ a FROM t1 WHERE a = 1 AND b = 2 AND c = 3;
48+
--echo # Force the use of i_a, i_b, i_c indexes, i_c index is used.
49+
EXPLAIN EXTENDED SELECT /*+ INDEX(t1 i_a, i_b) JOIN_INDEX(t1 i_c) */ * FROM t1 WHERE a = 1 AND b = 2 AND c = 3;
50+
51+
--echo # Test range index access
52+
EXPLAIN EXTENDED SELECT a FROM t1 WHERE a > 1 AND a < 3;
53+
--echo # Indexes are forbidden, full scan is employed
54+
EXPLAIN EXTENDED SELECT /*+ NO_INDEX(t1)*/a FROM t1 WHERE a > 1 AND a < 3;
55+
EXPLAIN EXTENDED SELECT /*+ NO_JOIN_INDEX(t1)*/a FROM t1 WHERE a > 1 AND a < 3;
56+
--echo # Indexes are forbidden for grouping and ordering but are usable for data access
57+
EXPLAIN EXTENDED SELECT /*+ NO_GROUP_INDEX(t1) NO_ORDER_INDEX(t1)*/a FROM t1 WHERE a > 1 AND a < 3;
58+
--echo # Index "i_a" is forbidden, "i_ab" is used instead
59+
EXPLAIN EXTENDED SELECT /*+ NO_INDEX(t1 i_a)*/a FROM t1 WHERE a > 1 AND a < 3;
60+
61+
--echo # Usable indexes are forbidden, full scan is employed
62+
EXPLAIN EXTENDED SELECT /*+ NO_INDEX(t1 i_a, i_ab)*/a FROM t1 WHERE a > 1 AND a < 3;
63+
64+
EXPLAIN EXTENDED SELECT /*+ INDEX(t1 i_ab)*/a FROM t1 WHERE a > 1 AND a < 3;
65+
66+
--echo # Full scan is more efficient for this query, so indexes are not used by default:
67+
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a < 8;
68+
--echo # Force using of any index:
69+
EXPLAIN EXTENDED SELECT /*+ index(t1)*/* FROM t1 WHERE a < 8;
70+
--echo # Force using of a particular index:
71+
EXPLAIN EXTENDED SELECT /*+ index(t1 i_a)*/* FROM t1 WHERE a < 8;
72+
73+
--echo # Ignore i_ab index, i_b index is used.
74+
EXPLAIN EXTENDED SELECT /*+ NO_INDEX(t1 i_ab) */ a, max(b) FROM t1 WHERE b = 2 GROUP BY a;
75+
--echo # Ignore i_ab index, i_b index is used.
76+
EXPLAIN EXTENDED SELECT /*+ NO_JOIN_INDEX(t1 i_ab) */ a, max(b) FROM t1 WHERE b = 2 GROUP BY a;
77+
--echo # Force i_ab index for GROUP BY, i_ab index scan is used.
78+
EXPLAIN EXTENDED SELECT /*+ GROUP_INDEX(t1 i_ab) */ a, max(b) FROM t1 GROUP BY a;
79+
--echo # Force i_ab index for JOIN, i_ab loose index scan is used.
80+
EXPLAIN EXTENDED SELECT /*+ JOIN_INDEX(t1 i_ab) */ a, max(b) FROM t1 GROUP BY a;
81+
--echo # Ignore i_ab for sorting rows. i_a index is used for sorting.
82+
EXPLAIN EXTENDED SELECT /*+ NO_ORDER_INDEX(t1 i_ab) */ a FROM t1 ORDER BY a;
83+
--echo # Ignore i_a for sorting rows. i_ab is used for sorting.
84+
EXPLAIN EXTENDED SELECT /*+ NO_ORDER_INDEX(t1 i_a) */ a FROM t1 ORDER BY a;
85+
--echo # Force i_ab index for sorting rows.
86+
EXPLAIN EXTENDED SELECT /*+ ORDER_INDEX(t1 i_ab) */ a FROM t1 ORDER BY a;
87+
--echo # Force i_a index for sorting rows.
88+
EXPLAIN EXTENDED SELECT /*+ ORDER_INDEX(t1 i_a) */ a FROM t1 ORDER BY a;
89+
--echo # Ignore all indexes.
90+
EXPLAIN EXTENDED SELECT /*+ NO_INDEX(t1) */ * FROM t1 WHERE a = 1 AND b = 2 AND c = 3;
91+
--echo # Check if old-style hints work if no new hints are specified.
92+
EXPLAIN EXTENDED SELECT /*+ NO_MRR(t1) */ * FROM t1 IGNORE INDEX (i_a)
93+
WHERE a = 1 AND b = 2 AND c = 3;
94+
95+
--echo # Check that old-style hint is silently ignored if a new hint is specified.
96+
EXPLAIN EXTENDED SELECT /*+ INDEX(t1 i_a) */ * FROM t1 IGNORE INDEX(i_a)
97+
WHERE a = 1 AND b = 2 AND c = 3;
98+
99+
--echo # No conflicts between different hints for same indexes
100+
EXPLAIN EXTENDED
101+
SELECT /*+ MRR(t1 i_a, i_b, i_ab) NO_ICP(t1 i_a, i_b, i_ab) JOIN_INDEX(t1 i_a, i_b) ORDER_INDEX(t1 i_a, i_ab) */
102+
a FROM t1;
103+
104+
--echo # Check index hints with UPDATE/DELETE commands.
105+
--echo # By default, "i_ab" index is used
106+
EXPLAIN EXTENDED UPDATE t1 SET d = 1 WHERE a = 1 AND b = 2 AND c = 3;
107+
--echo # Force i_a index to be used.
108+
EXPLAIN EXTENDED UPDATE /*+ INDEX(t1 i_a) */ t1 SET d = 1 WHERE a = 1 AND b = 2 AND c = 3;
109+
--echo # By default, "i_ab" index is used
110+
EXPLAIN EXTENDED DELETE FROM t1 WHERE a = 1 AND b = 2 AND c = 3;
111+
--echo # Forbid i_ab index for DELETE.
112+
EXPLAIN EXTENDED DELETE /*+ NO_INDEX(t1 i_ab) */ FROM t1 WHERE a = 1 AND b = 2 AND c = 3;
113+
114+
DROP TABLE t1;

sql/mem_root_array.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#ifndef MEM_ROOT_ARRAY_INCLUDED
1818
#define MEM_ROOT_ARRAY_INCLUDED
1919

20+
#include <type_traits>
2021
#include <my_alloc.h>
2122

2223
/**
@@ -44,7 +45,9 @@
4445
compilers we use.
4546
*/
4647

47-
template<typename Element_type, bool has_trivial_destructor>
48+
template<typename Element_type,
49+
bool has_trivial_destructor=
50+
std::is_trivially_destructible<Element_type>::value>
4851
class Mem_root_array
4952
{
5053
public:
@@ -263,5 +266,4 @@ class Mem_root_array
263266
}
264267
};
265268

266-
267269
#endif // MEM_ROOT_ARRAY_INCLUDED

0 commit comments

Comments
 (0)