将大查询拆分成小查询,每个查询功能完全一样,只是一小部分,每次只返回一小部分查询结果。
比如在删除旧数据的时候,如果用一个大的语句一次性删的话,则可能需要一次性锁住很多数据、占满整个事务日志、耗尽系统资源、阻塞其它查询任务。如果将一个大的删除语句拆分成若干个较小的删除语句,可以提升MySQL的性能。一次删除一万行数据一般来说是一个比较高效并且对服务器影响最小的做法。
分解关联查询的优势
多数连接MySQL的库函数都可以获得全部结果集并缓存在内存中,还可以逐行获取需要的数据。默认一般是获得全部结果集并缓存到内存中。MySQL通常需要等所有的数据都已经发送给客户端才能释放这条查询所占用的资源,所以接收全部结果并缓存通常可以减少服务器的压力,让查询能够早点结束,早点释放相应的资源。
数据库的关联并不总是按照查询中指定的顺序进行,优化器可能会改变其关联顺序,生成最优的执行计划。
如果使用min()获取最小值时,可以查询B-Tree索引最左端的记录,MySQL可以直接获取索引的第一行记录。优化器会将这个表达式作为一个常数对待,max()也是如此。如果MySQL使用了这个类型的优化,在explain时就会看到“select tables optimized away”
。它表示优化器已经从执行计划中移除了该表,并通过一个常量取而代之。
当MySQL检测到一个表达式可以转化为常数的时候,就会一直将该表达式作为常量进行优化处理。
当索引中的列包含所有查询中需要使用的列时,MySQL就可以使用索引返回需要的数据,而无须查询对应的数据行。
可以通过limit主动终止查询。
MySQL对任何关联都执行嵌套循环关联操作,即MySQL先在一个表中循环取出单条数据,然后再嵌套循环到下一个表中寻找匹配的行,依次下去,直到找到所有表中匹配的行为止。然后根据各个表匹配的行,返回查询需要的各个列。
在解析和优化阶段,MySQL将生成查询对应的执行计划,MySQL的查询执行引擎则根据这个执行计划来完成整个查询。这里的执行计划是一个数据结构,而不是像很多其他数据库那样会生成对应的字节码。
查询执行阶段,只是简单地根据执行计划给出的指令逐步执行。在根据执行计划逐步执行的过程中,有大量的操作需要通过调用存储引擎实现的接口来完成,这些即可被称为“handler API”
。
MySQL在优化阶段就会为每个表创建一个handler实例,优化器根据这些实例的接口可以获取表的相关信息,包括表的所有列名、索引统计信息等。
做法1:假设每页显示10条记录,那么每次查询时用limit返回11条记录,并显示其中的10条,如果第11条存在,那么就显示下一页按钮,否则就说明没有更多的数据。 做法2:现货区并缓存较多的数据,比如先查询1000行,然后每次分页都从这个缓存中获取,如果结果集小于1000,就可以在页面上显示所有的分页链接,因为数据在缓存中,这样做性能不会出现问题。如果结果集大于1000,则可以在页面上加一个查询更多数据的按钮。
这两种方式逗比每次获取全部结果集,再抛弃不需要的数据的方式效率高。