mysql hint的概念是什么

68次阅读
没有评论

共计 3234 个字符,预计需要花费 9 分钟才能阅读完成。

这篇文章主要介绍了 mysql hint 的概念是什么的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇 mysql hint 的概念是什么文章都会有所收获,下面我们一起来看看吧。

在 mysql 中,hint 指的是“查询优化提示”,会提示优化器按照一定的方式来生成执行计划进行优化,让用户的 sql 语句更具灵活性;Hint 可基于表的连接顺序、方法、访问路径、并行度等规则对 DML(数据操纵语言,Data Manipulation Language)语句产生作用。

本教程操作环境:windows7 系统、mysql8 版本、Dell G3 电脑。

我们在操作表、字段或索引时可以添加 comment 来增强代码可读性,以便他人快速读懂代码,这是对使用数据库的人的一种提示;同样的,还有一种提示,叫做 hint,是给数据库的提示。

何谓 hint

hint 指的是“查询优化提示”,它会提示优化器按照一定的方式去优化,让你的 sql 语句更具灵活性,这会让你的查询更快,当然也可能更慢,这完全取决于你对优化器的理解和场景的了解。

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

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

使用的优化器类型;基于代价的优化器的优化目标,是 all_rows 还是 first_rows;表的访问路径,是全表扫描,还是索引扫描,还是直接用 rowid;表之间的连接类型;表之间的连接顺序;语句的并行程度;

常用 hint

强制索引 FORCE INDEX
SELECT * FROM tbl FORCE INDEX (FIELD1) …

忽略索引 IGNORE INDEX
SELECT * FROM tbl IGNORE INDEX (FIELD1, FIELD2) …

关闭查询缓冲 SQL_NO_CACHE
SELECT SQL_NO_CACHE field1, field2 FROM tbl;
需要查询实时数据且频率不高时,可以考虑把缓冲关闭,即不论此 SQL 是否曾被执行,MySQL 都不会在缓冲区中查找。

强制查询缓冲 SQL_CACHE
SELECT SQL_CACHE * FROM tbl;
功能同上一条相反,但仅在 my.ini 中的 query_cache_type 设为 2 时起作用。

优先操作 HIGH_PRIORITY
HIGH_PRIORITY 可以使用在 select 和 insert 操作中,让 MYSQL 知道,这个操作优先进行。
SELECT HIGH_PRIORITY * FROM tbl;

滞后操作 LOW_PRIORITY
LOW_PRIORITY 可以使用在 insert 和 update 操作中,让 mysql 知道,这个操作滞后。
update LOW_PRIORITY tbl set field1= where field1= …

延时插入 INSERT DELAYED
INSERT DELAYED INTO tbl set field1= …
指客户端提交插入数据申请,MySQL 返回 OK 状态却并未实际执行,而是存储在内存中排队,当 mysql 有空余时再插入。
一个重要的好处是,来自多个客户端的插入请求被集中在一起,编写入一个块,比独立执行许多插入要快很多。
坏处是,不能返回自增 ID,以及系统崩溃时,MySQL 还未来得及被插入的数据将会丢失。

强制连接顺序 STRAIGHT_JOIN
SELECT tbl.FIELD1, tbl2.FIELD2 FROM tbl STRAIGHT_JOIN tbl2 WHERE …
由上面的 SQL 语句可知,通过 STRAIGHT_JOIN 强迫 MySQL 按 tbl、tbl2 的顺序连接表。如果你认为按自己的顺序比 MySQL 推荐的顺序进行连接的效率高的话,就可以通过 STRAIGHT_JOIN 来确定连接顺序。

不常用

强制使用临时表 SQL_BUFFER_RESULT
SELECT SQL_BUFFER_RESULT * FROM tbl WHERE …
当我们查询的结果集中的数据比较多时,可以通过 SQL_BUFFER_RESULT. 选项强制将结果集放到临时表中,这样就可以很快地释放 MySQL 的表锁(这样其它的 SQL 语句就可以对这些记录进行查询了),并且可以长时间地为客户端提供大记录集。

分组使用临时表 SQL_BIG_RESULT 和 SQL_SMALL_RESULT
SELECT SQL_BUFFER_RESULT FIELD1, COUNT(*) FROM tbl GROUP BY FIELD1;
对 SELECT 语句有效,告诉 MySQL 优化去对 GROUP BY 和 DISTINCT 查询如何使用临时表排序,SQL_SMALL_RESULT 表示结果集很小,可以直接在内存的临时表排序;反之则很大,需要使用磁盘临时表排序。

SQL_CALC_FOUND_ROWS
它其实不是优化器提示,也不影响优化器的执行计划,但会让 mysql 返回的结果集中包含本次操作影响的总行数,需与 FOUND_ROWS() 联用。
SQL_CALC_FOUND_ROWS 通知 MySQL 将本次处理的行数记录下来;FOUND_ROWS() 用于取出被记录的行数,可以应用到分页场景。
一般的分页写法为:先查总数,计算页数,再查询某一页的详情。
SELECT COUNT(*) from tbl WHERE …
SELECT * FROM tbl WHERE … limit m,n
但借助 SQL_CALC_FOUND_ROWS,可以简化成如下写法:
SELECT SQL_CALC_FOUND_ROWS * FROM tbl WHERE … limit m,n;
SELECT FOUND_ROWS();
第二条 SELECT 将返回第一条 SELECT 不带 limit 时的总行数,如此只需执行一次较耗时的复杂查询就可同时得到总行数。

LOCK IN SHARE MODE、FOR UPDATE
同样的,这俩也不是优化提示,是控制 SELECT 语句的锁机制,只对行级锁有效,即 InnoDB 支持。

扩展知识:

概念和区别

SELECT … LOCK IN SHARE MODE 添加的是 IS 锁(意向共享锁),即在符合条件的 rows 上都加了共享锁,其他 session 可读取记录,亦可继续添加 IS 锁,但无法修改,直到这个加锁的 session done(否则直接锁等待超时)。

SELECT … FOR UPDATE 添加的是 IX 锁 (意向排它锁),即符合条件的 rows 上都加了排它,其他 session 无法给这些记录添加任何 S 锁或 X 锁。如果不存在一致性非锁定读的话,则其他 session 是无法读取和修改这些记录的,但 innodb 有非锁定读(快照读不需要加锁)。
因此,for update 的加锁方式只是比 lock in share mode 的方式多阻塞了 select…lock in share mode 的查询方式,并不会阻塞快照读。

应用场景

LOCK IN SHARE MODE 的适用于两张存在关系的表的写场景,以 mysql 官方例子来说,一个表是 child 表,一个是 parent 表,假设 child 表的某一列 child_id 映射到 parent 表的 c_child_id 列,从业务角度讲,此时直接 insert 一条 child_id=100 记录到 child 表是存在风险的,因为 insert 的同时可能存在 parent 表执行了删除 c_child_id=100 的记录,业务数据有不一致的风险。正确方法是先执行 select * from parent where c_child_id=100 lock in share mode,锁定 parent 表的这条记录,然后执行 insert into child(child_id) values (100)。

关于“mysql hint 的概念是什么”这篇文章的内容就介绍到这里,感谢各位的阅读!相信大家对“mysql hint 的概念是什么”知识都有一定的了解,大家如果还想学习更多知识,欢迎关注丸趣 TV 行业资讯频道。

正文完
 
丸趣
版权声明:本站原创文章,由 丸趣 2023-07-13发表,共计3234字。
转载说明:除特殊说明外本站除技术相关以外文章皆由网络搜集发布,转载请注明出处。
评论(没有评论)