sqlhint的简单介绍

本篇文章给大家谈谈sqlhint,以及对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。

本文目录一览:

如何通过加Hint稳定SQL的执行计划

修改SQL语句大含,使用HINT,使SQL语句按HINT指定的执行计划进行执行。这需要修改应用,同时需要逐条SQL语句进行,加上测试和发布,时间庆带较长,成本较高滚差笑,风险也较大。

mysql hint是什么意思

在键租谨开始演示之前,我们先介绍下两个概念。

概念一,数据的可选择性基数,也就是常说的cardinality值。

查询优化器在生成各种执行计划之前,得先从统计信息中取得相关数据,这样才能估算每步操作所涉及到的记录数,而这个相关数据就是cardinality。简单来说,就是每个值在每个字段中的唯一值分布状态。

比如表t1有100行记录,其中一列为f1。f1中唯一值的个数可以是100个,也可以是1个,当然也可以是1到100之间的任何一个数字。这里唯一值越的多少,就是这个列的可选择基数。

那看到这里我们就明白了,为什么要在基数高的字段上建立索引,而基数低的的字段建立索引反而没有全表扫描来的快。当然这个只是一方面,至于更深入的探讨就不在我这篇探讨的范围了。

概念二,关于HINT的使用。

这里我来说下HINT是什么,在什么时候用。

HINT简单来说就是在某些特定的场景下人工协助MySQL优化器的工作,使她生成最优的执行计划。一般来说,优化器的执行计划都是最优化的,不过在某些特定场景下,执行计划可能不是最优化。

比如:表t1经过大稿基量的频繁更新操作,(UPDATE,DELETE,INSERT),cardinality已经很不准确了,这时候刚好执行了一条SQL,那么有可能这条SQL的执行计划就不是最优的。为什么说有可能呢?

来看下具体演示

譬如,以下两条SQL,

A:

select * from t1 where f1 = 20;

B:

select * from t1 where f1 = 30;

如果f1的值刚好频繁更新的值为30,并且没有达到MySQL自动更新cardinality值的临界值或者说用户设置了手动更新又或者用户减少了sample page等等,那么对这两条语句来说,可能不准确的就是B了。

这里顺带说下,MySQL提供了自动更新和手动更新表cardinality值的方法,因篇幅有限,需要的可以查阅手册。

那回到正题上,MySQL 8.0 带来了几个HINT,我今天就举个index_merge的例子。

示例表结构:

mysql desc t1;+------------+--------------+------+-----+---------+----------------+| Field      | Type         | Null | Key | Default | Extra          |+------------+--------------+------+-----+---------+----------------+| id         | int(11)      | NO   | PRI | NULL    | auto_increment || rank1      | int(11)      | YES  | MUL | NULL    |                || rank2      | int(11)      | YES  | MUL | NULL    |                || log_time   | datetime     | YES  | MUL | NULL    |                || prefix_uid | varchar(100) | YES  |     | NULL    |                || desc1      | text         | YES  |     | NULL    |                || rank3      | int(11)      | YES  | MUL | NULL    |  型启              |+------------+--------------+------+-----+---------+----------------+7 rows in set (0.00 sec)

表记录数:

mysql select count(*) from t1;+----------+| count(*) |+----------+|    32768 |+----------+1 row in set (0.01 sec)

这里我们两条经典的SQL:

SQL C:

select * from t1 where rank1 = 1 or rank2 = 2 or rank3 = 2;

SQL D:

select * from t1 where rank1 =100  and rank2 =100  and rank3 =100;

表t1实际上在rank1,rank2,rank3三列上分别有一个二级索引。

那我们来看SQL C的查询计划。

显然,没有用到任何索引,扫描的行数为32034,cost为3243.65。

mysql explain  format=json select * from t1  where rank1 =1 or rank2 = 2 or rank3 = 2\G*************************** 1. row ***************************EXPLAIN: {  "query_block": {    "select_id": 1,    "cost_info": {      "query_cost": "3243.65"    },    "table": {      "table_name": "t1",      "access_type": "ALL",      "possible_keys": [        "idx_rank1",        "idx_rank2",        "idx_rank3"      ],      "rows_examined_per_scan": 32034,      "rows_produced_per_join": 115,      "filtered": "0.36",      "cost_info": {        "read_cost": "3232.07",        "eval_cost": "11.58",        "prefix_cost": "3243.65",        "data_read_per_join": "49K"      },      "used_columns": [        "id",        "rank1",        "rank2",        "log_time",        "prefix_uid",        "desc1",        "rank3"      ],      "attached_condition": "((`ytt`.`t1`.`rank1` = 1) or (`ytt`.`t1`.`rank2` = 2) or (`ytt`.`t1`.`rank3` = 2))"    }  }}1 row in set, 1 warning (0.00 sec)

我们加上hint给相同的查询,再次看看查询计划。

这个时候用到了index_merge,union了三个列。扫描的行数为1103,cost为441.09,明显比之前的快了好几倍。

mysql explain  format=json select /*+ index_merge(t1) */ * from t1  where rank1 =1 or rank2 = 2 or rank3 = 2\G*************************** 1. row ***************************EXPLAIN: {  "query_block": {    "select_id": 1,    "cost_info": {      "query_cost": "441.09"    },    "table": {      "table_name": "t1",      "access_type": "index_merge",      "possible_keys": [        "idx_rank1",        "idx_rank2",        "idx_rank3"      ],      "key": "union(idx_rank1,idx_rank2,idx_rank3)",      "key_length": "5,5,5",      "rows_examined_per_scan": 1103,      "rows_produced_per_join": 1103,      "filtered": "100.00",      "cost_info": {        "read_cost": "330.79",        "eval_cost": "110.30",        "prefix_cost": "441.09",        "data_read_per_join": "473K"      },      "used_columns": [        "id",        "rank1",        "rank2",        "log_time",        "prefix_uid",        "desc1",        "rank3"      ],      "attached_condition": "((`ytt`.`t1`.`rank1` = 1) or (`ytt`.`t1`.`rank2` = 2) or (`ytt`.`t1`.`rank3` = 2))"    }  }}1 row in set, 1 warning (0.00 sec)

我们再看下SQL D的计划:

不加HINT,

mysql explain format=json select * from t1 where rank1 =100 and rank2 =100 and rank3 =100\G*************************** 1. row ***************************EXPLAIN: {  "query_block": {    "select_id": 1,    "cost_info": {      "query_cost": "534.34"    },    "table": {      "table_name": "t1",      "access_type": "ref",      "possible_keys": [        "idx_rank1",        "idx_rank2",        "idx_rank3"      ],      "key": "idx_rank1",      "used_key_parts": [        "rank1"      ],      "key_length": "5",      "ref": [        "const"      ],      "rows_examined_per_scan": 555,      "rows_produced_per_join": 0,      "filtered": "0.07",      "cost_info": {        "read_cost": "478.84",        "eval_cost": "0.04",        "prefix_cost": "534.34",        "data_read_per_join": "176"      },      "used_columns": [        "id",        "rank1",        "rank2",        "log_time",        "prefix_uid",        "desc1",        "rank3"      ],      "attached_condition": "((`ytt`.`t1`.`rank3` = 100) and (`ytt`.`t1`.`rank2` = 100))"    }  }}1 row in set, 1 warning (0.00 sec)

加了HINT,

mysql explain format=json select /*+ index_merge(t1)*/ * from t1 where rank1 =100 and rank2 =100 and rank3 =100\G*************************** 1. row ***************************EXPLAIN: {  "query_block": {    "select_id": 1,    "cost_info": {      "query_cost": "5.23"    },    "table": {      "table_name": "t1",      "access_type": "index_merge",      "possible_keys": [        "idx_rank1",        "idx_rank2",        "idx_rank3"      ],      "key": "intersect(idx_rank1,idx_rank2,idx_rank3)",      "key_length": "5,5,5",      "rows_examined_per_scan": 1,      "rows_produced_per_join": 1,      "filtered": "100.00",      "cost_info": {        "read_cost": "5.13",        "eval_cost": "0.10",        "prefix_cost": "5.23",        "data_read_per_join": "440"      },      "used_columns": [        "id",        "rank1",        "rank2",        "log_time",        "prefix_uid",        "desc1",        "rank3"      ],      "attached_condition": "((`ytt`.`t1`.`rank3` = 100) and (`ytt`.`t1`.`rank2` = 100) and (`ytt`.`t1`.`rank1` = 100))"    }  }}1 row in set, 1 warning (0.00 sec)

对比下以上两个,加了HINT的比不加HINT的cost小了100倍。

总结下,就是说表的cardinality值影响这张的查询计划,如果这个值没有正常更新的话,就需要手工加HINT了。相信MySQL未来的版本会带来更多的HINT。

[img]

Oracle,SQL语句中/*+ */是什么技术

oracle特有的hint,简单的说就是让数据库忽略自身的策略,按操作者想要的执行顺序来执雹盯行sql语句;

比如数据库樱空觉得一个查询要走索引,而你想要这条语句走全表扫描,就脊肆瞎可以使用hint,如:

SELECT /*+ FULL (s) */ col1 from table s where col2=:1

一句sql能加两个或者以上的hint吗

试好烂试:include iostream

#include 简袜谈stdio.h

int jc(int m){

if(m!=1) return m*jc(m-1);

else return 1;

}

int c(int m,int n){

if(m=n) return jc(m)/(jc(n)*jc(m-n));

}

int main(void){

int m,n;

scanf("%d%d"拦碰,m,n);

printf("%d\n",c(m,n));

return 0;

}

sql中有一些*/+ /*之类的符号是什么意思?

Oracle中这种东西叫做hint,是一种优化SQL的工具轿唤。不同的hint会导致不同的优化薯丛模式。

例如一句SQL可能这样写:

select a.id, a.name

from a, b

where a.date=b.date

假如这个语句执行起来很慢。我们就可以用hint指定某一种优化模式,使运行速度加快。比如说指定选用a表的a_indx这个索引,及b表的b_indx这个索引,闭手凯可以写作

select /*+ index(a a_indx) index(b b_indx) */

a.id, a.name

from a, b

where a.date = b.date

这样就实现了对SQL的优化。除了index这个hint以外,还有all_rows, first_rows,等等。

这个网站提供一个教程:

MySQL的特殊关键字提示:hint

我们知道在执行一条SQL语句时,MySQL会生成一个执行计划,而hint就是告诉查询优化亮辩器需要按照我们告诉它的方式来生成执行计划。型世

Hint可基于表的连接顺序、方法、访问路径、并行度等规则对DML(数据操纵语言,Data Manipulation Language)语句产生作用敬租缺,范围如下:

关于sqlhint和的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。

相关阅读

  • oraclesupport(Oracle support identifier)

    oraclesupport(Oracle support identifier)

    简介:Oracle Support是Oracle公司提供的一项重要的技术支持服务,旨在帮助客户解决Oracle软件产品在使用过程中遇到的问题,提高系统的稳定性和性能。本文将介绍Oracle Support的重要性以及具体的使用方法。一、Or...

    2024.04.17 09:55:21作者:intanet.cnTags:oraclesupport
  • hivetez(hive特征工程)

    hivetez(hive特征工程)

    标题:探索Hivetez的未来简介:Hivetez是一家领先的IT技术公司,在区块链和加密货币领域有着深厚的技术积累。本文将探索Hivetez在IT技术领域的未来发展方向和创新技术。一、区块链技术的应用Hivetez致力于将区块链技术应用于...

    2024.04.17 07:22:22作者:intanet.cnTags:hivetez
  • mysql或的简单介绍

    mysql或的简单介绍

    MySQL数据库简介MySQL是一种开源的关系型数据库系统,广泛应用于Web应用程序的开发中。它支持多种操作系统,包括Windows、Linux和Mac OS等,同时也支持多种编程语言,如PHP、Java和Python。MySQL具有高性能...

    2024.04.17 06:55:17作者:intanet.cnTags:mysql或
  • redis创建表(redis创建表命令)

    redis创建表(redis创建表命令)

    简介:Redis是一种内存数据库,广泛应用于缓存和消息传递等领域。在使用Redis进行开发时,我们经常需要创建表来存储数据。本文将介绍如何在Redis中创建表。一级标题:如何在Redis中创建表二级标题:连接Redis数据库首先,我们需要连...

    2024.04.16 12:55:11作者:intanet.cnTags:redis创建表
  • mongodbapi的简单介绍

    mongodbapi的简单介绍

    MongoDB是一种开源的NoSQL数据库管理系统,它具有高性能、高可用性和可伸缩性的特点,能够处理大量的非结构化数据。MongoDB提供了一套丰富的API,允许开发人员在应用程序中使用各种编程语言来操作和管理数据库。# 什么是MongoD...

    2024.04.16 12:44:25作者:intanet.cnTags:mongodbapi
  • redis3(redis30集群)

    redis3(redis30集群)

    简介:Redis是一种开源的高性能键值存储数据库,常用作缓存、消息队列、排行榜等场景。Redis3是Redis的一个重要版本,它带来了许多新的特性和性能优化,使得Redis在大规模应用中表现更加出色。本文将介绍Redis3的一些重要特性和使...

    2024.04.16 12:22:11作者:intanet.cnTags:redis3
  • db-3(db3双向触发二极管好坏的测量)

    db-3(db3双向触发二极管好坏的测量)

    IT技术在当今社会中扮演着重要的角色,它贯穿着各个行业和领域,为我们的生活带来了巨大的便利和发展。本文将介绍关于数据库技术的知识和应用,探讨数据库技术在IT领域中的重要性和作用。# 数据库技术的概念和分类数据库技术是指通过计算机系统来管理和...

    2024.04.16 11:55:16作者:intanet.cnTags:db-3
  • oracle中sysdate(oracle中sysdate返回多个日期)

    oracle中sysdate(oracle中sysdate返回多个日期)

    标题:Oracle中sysdate的用法简介:在Oracle数据库中,sysdate是一个函数,可用于获取当前的系统日期和时间。它常用于数据库操作中,例如插入、更新数据时记录操作的时间。一、sysdate函数的语法sysdate函数的基本语...

    2024.04.16 08:44:11作者:intanet.cnTags:oracle中sysdate