MySQL的特殊关键字提示:hint

MySQL的特殊关键字提示:hint

2023年6月27日发(作者:)

MySQL的特殊关键字提⽰:hint我们在操作表、字段或索引时可以添加

comment 来增强代码可读性,以便他⼈快速读懂代码,这是对使⽤数据库的⼈的⼀种提⽰;同样的,还有⼀种提⽰,叫做hint,是给数据库的提⽰。何谓 hint我们知道在执⾏⼀条SQL语句时,MySQL会⽣成⼀个执⾏计划,⽽hint就是告诉查询优化器需要按照我们告诉它的⽅式来⽣成执⾏计划。Hint可基于表的连接顺序、⽅法、访问路径、并⾏度等规则对DML(数据操纵语⾔,Data Manipulation Language)语句产⽣作⽤,范围如下:使⽤的优化器类型;基于代价的优化器的优化⽬标,是all_rows还是first_rows;表的访问路径,是全表扫描,还是索引扫描,还是直接⽤rowid;表之间的连接类型;表之间的连接顺序;语句的并⾏程度;常⽤ hint1. 强制索引 FORCE INDEXSELECT * FROM tbl FORCE INDEX (FIELD1) …2. 忽略索引 IGNORE INDEXSELECT * FROM tbl IGNORE INDEX (FIELD1, FIELD2) …3. 关闭查询缓冲 SQL_NO_CACHESELECT SQL_NO_CACHE field1, field2 FROM tbl;需要查询实时数据且频率不⾼时,可以考虑把缓冲关闭,即不论此SQL是否曾被执⾏,MySQL都不会在缓冲区中查找。4. 强制查询缓冲 SQL_CACHESELECT SQL_CACHE * FROM tbl;功能同上⼀条相反,但仅在中的query_cache_type设为2时起作⽤。5. 优先操作 HIGH_PRIORITYHIGH_PRIORITY可以使⽤在select和insert操作中,让MYSQL知道,这个操作优先进⾏。SELECT HIGH_PRIORITY * FROM tbl;6. 滞后操作 LOW_PRIORITYLOW_PRIORITY可以使⽤在insert和update操作中,让mysql知道,这个操作滞后。update LOW_PRIORITY tbl set field1= where field1= …7. 延时插⼊ INSERT DELAYEDINSERT DELAYED INTO tbl set field1= …指客户端提交插⼊数据申请,MySQL返回OK状态却并未实际执⾏,⽽是存储在内存中排队,当mysql有空余时再插⼊。⼀个重要的好处是,来⾃多个客户端的插⼊请求被集中在⼀起,编写⼊⼀个块,⽐独⽴执⾏许多插⼊要快很多。坏处是,不能返回⾃增ID,以及系统崩溃时,MySQL还未来得及被插⼊的数据将会丢失。8. 强制连接顺序 STRAIGHT_JOINSELECT 1, 2 FROM tbl STRAIGHT_JOIN tbl2 WHERE …由上⾯的SQL语句可知,通过STRAIGHT_JOIN强迫MySQL按tbl、tbl2的顺序连接表。如果你认为按⾃⼰的顺序⽐MySQL推荐的顺序进⾏连接的效率⾼的话,就可以通过STRAIGHT_JOIN来确定连接顺序。不常⽤9. 强制使⽤临时表 SQL_BUFFER_RESULTSELECT SQL_BUFFER_RESULT * FROM tbl WHERE …当我们查询的结果集中的数据⽐较多时,可以通过SQL_BUFFER_RESULT.选项强制将结果集放到临时表中,这样就可以很快地释放MySQL的表锁(这样其它的SQL语句就可以对这些记录进⾏查询了),并且可以长时间地为客户端提供⼤记录集。10. 分组使⽤临时表 SQL_BIG_RESULT和SQL_SMALL_RESULTSELECT SQL_BUFFER_RESULT FIELD1, COUNT(*) FROM tbl GROUP BY FIELD1;对SELECT语句有效,告诉MySQL优化去对GROUP BY和DISTINCT查询如何使⽤临时表排序,SQL_SMALL_RESULT表⽰结果集很⼩,可以直接在内存的临时表排序;反之则很⼤,需要使⽤磁盘临时表排序。11. 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时的总⾏数,如此只需执⾏⼀次较耗时的复杂查询就可同时得到总⾏数。12. 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的⽅式多阻塞了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)。

发布者:admin,转转请注明出处:http://www.yc00.com/news/1687818522a47824.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信