Oracle兼容-语法-Oracle HINT


1. 语法

在SQL语句中,HINT 语法采用 /*+ ... */ 包含起来,有以下几种不同用法。

    1. 在DML语句的前部
  1. SELECT /*+ hint_name */ ...
  2. INSERT /*+ hint_name */ ...
  3. UPDATE /*+ hint_name */ ...
  4. DELETE /*+ hint_name */ ...
  5. REPLACE /*+ hint_name */ ...
    1. 在查询块的前部
  1. (SELECT /*+ hint_name */ ... )
  2. (SELECT ... ) UNION (SELECT /*+ hint_name */ ... )
  3. (SELECT /*+ hint_name */ ... ) UNION (SELECT /*+ hint_name */ ... )
  4. UPDATE ... WHERE x IN (SELECT /*+ hint_name */ ...)
  5. INSERT ... SELECT /*+ hint_name */ ...
    1. EXPLAIN
  1. EXPLAIN SELECT /*+ hint_name */ ...
  2. EXPLAIN UPDATE ... WHERE x IN (SELECT /*+ hint_name */ ...)

2. 定义和用法

在GreatSQL中支持数个Oracle风格的HINT语法。

序号GreatSQLOracle
1HASH_JOIN, NO_HASH_JOINUSE_HASH(TABLE),NO_USE_HASH
2INDEX, NO_INDEXINDEX(TABLE INDEX_NAME), NO_INDEX
3INDEX_MERGEADD_EQUAL TABLE INDEX_NAM1,INDEX_NAM2,…
4JOIN_INDEX, NO_JOIN_INDEXINDEX_JOIN(TABLE INDEX_NAME)
5JOIN_PREFIXLEADING(TABLE)
6MERGE, NO_MERGEMERGE(TABLE), NO_MERGE(TABLE)
7ORDER_INDEXINDEX_ASC(TABLE INDEX_NAME)
8SEMIJOIN, NO_SEMIJOINSEMIJOIN, NO_SEMIJOIN
9SKIP_SCAN, NO_SKIP_SCANINDEX_SS, NO_INDEX_SS

GreatSQL与Oracle同名对应 HINT 有序号 2(INDEXNO_INDEX)、6(MERGENO_MERGE)、8(SEMIJOINNO_SEMIJOIN)三个,其余的名字虽然不同或接近,但功能是一样的。

3. 示例

3.1 构造测试环境

    1. 初始化测试表
  1. greatsql> CREATE TABLE t0 (
  2. c1 BIGINT NOT NULL AUTO_INCREMENT,
  3. c2 VARCHAR(500) DEFAULT NULL,
  4. c3 VARCHAR(500) DEFAULT NULL,
  5. c4 VARCHAR(500) DEFAULT NULL,
  6. PRIMARY KEY (c1),
  7. KEY idx1 (c1),
  8. KEY idx2 (c2),
  9. KEY idx3 (c3),
  10. KEY idx4 (c4)
  11. ) ENGINE=InnoDB;
    1. 创建随机字符串函数用于生成测试数据
  1. greatsql> DELIMITER //
  2. greatsql> CREATE FUNCTION `randStr`(n INT) RETURNS VARCHAR(255) CHARSET utf8mb4
  3. DETERMINISTIC
  4. BEGIN
  5. DECLARE chars_str varchar(100) DEFAULT 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
  6. DECLARE return_str VARCHAR(255) DEFAULT '';
  7. DECLARE i INT DEFAULT 0;
  8. WHILE i < n DO
  9. SET return_str = concat(return_str, substring(chars_str, FLOOR(1 + RAND() * 62), 1));
  10. SET i = i + 1;
  11. END WHILE;
  12. RETURN return_str;
  13. END; //
    1. 创建填充测试数据存储过程
  1. greatsql> DELIMITER //
  2. greatsql> CREATE PROCEDURE `fill_t0`(IN n INT)
  3. BEGIN
  4. DECLARE i INT DEFAULT 1;
  5. WHILE (i <= n ) DO
  6. INSERT INTO t0 (c2,c3,c4) VALUES(ROUND(RAND() * 5444000000000 + 0), randStr(ROUND(RAND() * 8 + 8)), randStr(ROUND(RAND() * 10 + 10)));
  7. set i=i+1;
  8. END WHILE;
  9. END; //
  10. greatsql> DELIMITER ;
    1. 填充测试数据
  1. greatsql> CALL fill_t0(10000);
    1. 建测试测试表t1,t2,t3,并插入数据
  1. greatsql> CREATE TABLE t1 (t1_id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, t1_val INT UNSIGNED, t1_str VARCHAR(300));
  2. greatsql> CREATE TABLE t2 (t2_id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, t2_val INT UNSIGNED, t2_str VARCHAR(300));
  3. greatsql> CREATE TABLE t3 (t3_id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, t3_val INT UNSIGNED, t3_str VARCHAR(300));
  4. greatsql> SET SESSION cte_max_recursion_depth = 10000;
  5. greatsql> INSERT INTO t1 (t1_val) WITH RECURSIVE digits(i) AS (SELECT 1 UNION ALL SELECT i+1 FROM digits WHERE i<10000) SELECT FLOOR(RAND()*100) FROM digits;
  6. greatsql> INSERT INTO t2 (t2_val) WITH RECURSIVE digits(i) AS (SELECT 1 UNION ALL SELECT i+1 FROM digits WHERE i<10000) SELECT FLOOR(RAND()*100) FROM digits;
  7. greatsql> INSERT INTO t3 (t3_val) WITH RECURSIVE digits(i) AS (SELECT 1 UNION ALL SELECT i+1 FROM digits WHERE i<10000) SELECT FLOOR(RAND()*50) FROM digits;
  8. greatsql> CREATE INDEX idx_t3_val ON t3(t3_val);

3.2 测试用例

    1. INDEX_MERGE 对应 ADD_EQUAL

说明:通过对比执行计划结果中的相关信息可知是否有效,如:"key": "union(idx2,idx3,idx4)"

  1. greatsql> EXPLAIN FORMAT=JSON SELECT * FROM t0 WHERE c2='1' OR c3='SCBd' OR c4='dafeiiEIGWJdfsdfsdfI'\G
  2. ...
  3. "access_type": "index_merge",
  4. "possible_keys": [
  5. "idx2",
  6. "idx3",
  7. "idx4"
  8. ],
  9. "key": "union(idx2,idx3,idx4)",
  10. "key_length": "2003,2003,2003",
  11. "rows_examined_per_scan": 3,
  12. "rows_produced_per_join": 3,
  13. "filtered": "100.00",
  14. ...
  15. greatsql> EXPLAIN FORMAT=JSON SELECT /*+ INDEX_MERGE(idx2,idx3,idx4) */ * FROM t0 WHERE c2='1' OR c3='SCBd' OR c4='dafeiiEIGWJdfsdfsdfI'\G
  16. ...
  17. "access_type": "index_merge",
  18. "possible_keys": [
  19. "idx2",
  20. "idx3",
  21. "idx4"
  22. ],
  23. "key": "union(idx2,idx3,idx4)",
  24. "key_length": "2003,2003,2003",
  25. "rows_examined_per_scan": 3,
  26. "rows_produced_per_join": 3,
  27. "filtered": "100.00",
  28. ...
  29. greatsql> EXPLAIN FORMAT=JSON SELECT /*+ ADD_EQUAL(idx2,idx3,idx4) */ * FROM t0 WHERE c2='1' OR c3='SCBd' OR c4='dafeiiEIGWJdfsdfsdfI'\G
  30. ...
  31. "access_type": "index_merge",
  32. "possible_keys": [
  33. "idx2",
  34. "idx3",
  35. "idx4"
  36. ],
  37. "key": "union(idx2,idx3,idx4)",
  38. "key_length": "2003,2003,2003",
  39. "rows_examined_per_scan": 3,
  40. "rows_produced_per_join": 3,
  41. "filtered": "100.00",
  42. ...
    1. JOIN_INDEX 对应 INDEX_JOIN

说明:通过对比执行计划结果中的相关信息可知是否有效,如:possible_keyskey

  1. greatsql> EXPLAIN PLAN FOR SELECT * FROM t0 WHERE c2='1593923265629';
  2. +----+-------------+-------+------------+------+---------------+------+---------+-------+------+----------+-------+
  3. | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
  4. +----+-------------+-------+------------+------+---------------+------+---------+-------+------+----------+-------+
  5. | 1 | SIMPLE | t0 | NULL | ref | idx2 | idx2 | 2003 | const | 1 | 100.00 | NULL |
  6. +----+-------------+-------+------------+------+---------------+------+---------+-------+------+----------+-------+
  7. greatsql> EXPLAIN PLAN FOR SELECT /*+ JOIN_INDEX(t0 idx2) */ * FROM t0 WHERE c2='1593923265629';
  8. +----+-------------+-------+------------+------+---------------+------+---------+-------+------+----------+-------+
  9. | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
  10. +----+-------------+-------+------------+------+---------------+------+---------+-------+------+----------+-------+
  11. | 1 | SIMPLE | t0 | NULL | ref | idx2 | idx2 | 2003 | const | 1 | 100.00 | NULL |
  12. +----+-------------+-------+------------+------+---------------+------+---------+-------+------+----------+-------+
  13. greatsql> EXPLAIN PLAN FOR SELECT /*+ NO_JOIN_INDEX(t0 idx2) */ * FROM t0 WHERE c2='1593923265629';
  14. +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
  15. | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
  16. +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
  17. | 1 | SIMPLE | t0 | NULL | ALL | NULL | NULL | NULL | NULL | 9834 | 0.01 | Using where |
  18. +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
  19. greatsql> EXPLAIN PLAN FOR SELECT /*+ INDEX_JOIN(t0 idx2) */ * FROM t0 WHERE c2='1593923265629';
  20. +----+-------------+-------+------------+------+---------------+------+---------+-------+------+----------+-------+
  21. | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
  22. +----+-------------+-------+------------+------+---------------+------+---------+-------+------+----------+-------+
  23. | 1 | SIMPLE | t0 | NULL | ref | idx2 | idx2 | 2003 | const | 1 | 100.00 | NULL |
  24. +----+-------------+-------+------------+------+---------------+------+---------+-------+------+----------+-------+
    1. JOIN_PREFIX 对应 LEADING(TABLE)

说明:通过对比执行计划结果中的相关信息可知是否有效,如:Table scan on t3 (cost=1005.00 rows=10000)

  1. greatsql> EXPLAIN FORMAT=tree SELECT * FROM t1, t2,t3 WHERE t2.t2_val=t1.t1_val AND t1.t1_val=t3.t3_val\G
  2. *************************** 1. row ***************************
  3. EXPLAIN: -> Nested loop inner join (cost=360001029.65 rows=2000000030)
  4. -> Inner hash join (t2.t2_val = t1.t1_val) (cost=10001024.44 rows=10000000)
  5. -> Table scan on t2 (cost=0.01 rows=10000)
  6. -> Hash
  7. -> Filter: (t1.t1_val is not null) (cost=1005.00 rows=10000)
  8. -> Table scan on t1 (cost=1005.00 rows=10000)
  9. -> Index lookup on t3 using idx_t3_val (t3_val=t1.t1_val) (cost=15.00 rows=200)
  10. greatsql> EXPLAIN FORMAT=tree SELECT /*+ JOIN_PREFIX(t3) */ * FROM t1, t2,t3 WHERE t2.t2_val=t1.t1_val AND t1.t1_val=t3.t3_val\G
  11. *************************** 1. row ***************************
  12. EXPLAIN: -> Inner hash join (t2.t2_val = t3.t3_val) (cost=10010030050.94 rows=10000000298)
  13. -> Table scan on t2 (cost=0.00 rows=10000)
  14. -> Hash
  15. -> Inner hash join (t1.t1_val = t3.t3_val) (cost=10001024.44 rows=10000000)
  16. -> Table scan on t1 (cost=0.01 rows=10000)
  17. -> Hash
  18. -> Table scan on t3 (cost=1005.00 rows=10000)
  19. greatsql> EXPLAIN FORMAT=tree SELECT /*+ LEADING(t3) */ * FROM t1, t2,t3 WHERE t2.t2_val=t1.t1_val AND t1.t1_val=t3.t3_val\G
  20. *************************** 1. row ***************************
  21. EXPLAIN: -> Inner hash join (t2.t2_val = t3.t3_val) (cost=10010030050.94 rows=10000000298)
  22. -> Table scan on t2 (cost=0.00 rows=10000)
  23. -> Hash
  24. -> Inner hash join (t1.t1_val = t3.t3_val) (cost=10001024.44 rows=10000000)
  25. -> Table scan on t1 (cost=0.01 rows=10000)
  26. -> Hash
  27. -> Table scan on t3 (cost=1005.00 rows=10000)
    1. ORDER_INDEX 对应 INDEX_ASC(TABLE INDEX_NAME)

说明:通过对比执行计划结果中的相关信息可知是否有效,如:possible_keyskey

  1. greatsql> EXPLAIN SELECT * FROM t0 WHERE c2='1593923265629' AND c3='asdfaldsjdfSDFASD' ORDER BY c1;
  2. +----+-------------+-------+------------+------+---------------+------+---------+-------+------+----------+-------------+
  3. | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
  4. +----+-------------+-------+------------+------+---------------+------+---------+-------+------+----------+-------------+
  5. | 1 | SIMPLE | t0 | NULL | ref | idx2,idx3 | idx2 | 2003 | const | 1 | 5.00 | Using where |
  6. +----+-------------+-------+------------+------+---------------+------+---------+-------+------+----------+-------------+
  7. greatsql> EXPLAIN SELECT /*+ ORDER_INDEX(t0 idx3,idx2) */ * FROM t0 WHERE c2='1593923265629' AND c3='asdfaldsjdfSDFASD' ORDER BY c1;
  8. +----+-------------+-------+------------+------+---------------+------+---------+------+-------+----------+-----------------------------+
  9. | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
  10. +----+-------------+-------+------------+------+---------------+------+---------+------+-------+----------+-----------------------------+
  11. | 1 | SIMPLE | t0 | NULL | ALL | NULL | NULL | NULL | NULL | 10095 | 0.01 | Using where; Using filesort |
  12. +----+-------------+-------+------------+------+---------------+------+---------+------+-------+----------+-----------------------------+
  13. greatsql> EXPLAIN SELECT /*+ ORDER_INDEX(t0 idx1,idx2) */ * FROM t0 WHERE c2='1593923265629' AND c3='asdfaldsjdfSDFASD' ORDER BY c1;
  14. +----+-------------+-------+------------+-------+---------------+------+---------+------+-------+----------+-------------+
  15. | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
  16. +----+-------------+-------+------------+-------+---------------+------+---------+------+-------+----------+-------------+
  17. | 1 | SIMPLE | t0 | NULL | index | NULL | idx1 | 8 | NULL | 10095 | 1.00 | Using where |
  18. +----+-------------+-------+------------+-------+---------------+------+---------+------+-------+----------+-------------+
  19. greatsql> EXPLAIN SELECT /*+ INDEX_ASC(t0 idx1,idx2) */ * FROM t0 WHERE c2='1593923265629' AND c3='asdfaldsjdfSDFASD' ORDER BY c1;
  20. +----+-------------+-------+------------+-------+---------------+------+---------+------+-------+----------+-------------+
  21. | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
  22. +----+-------------+-------+------------+-------+---------------+------+---------+------+-------+----------+-------------+
  23. | 1 | SIMPLE | t0 | NULL | index | NULL | idx1 | 8 | NULL | 10095 | 1.00 | Using where |
  24. +----+-------------+-------+------------+-------+---------------+------+---------+------+-------+----------+-------------+

问题反馈

联系我们

扫码关注微信公众号

greatsql-wx