mysql查询优化

合集下载

MySQL查询性能优化

MySQL查询性能优化

MySQL查询性能优化⼀、MySQL查询执⾏基础1. MySQL查询执⾏流程原理<1> 客户端发送⼀条查询给服务器。

<2> 服务器先检查查询缓存,如果命中了缓存,则⽴刻返回存储在缓存中的结果。

否则进⼊下⼀阶段。

<3> 服务器进⾏SQL解析、预处理,再由优化器⽣成对应的执⾏计划。

<4> MySQL根据优化器⽣成的执⾏计划,调⽤存储引擎的API来执⾏查询。

<5> MySQL将结果返回给客户端,同时保存⼀份到查询缓存中。

2. MySQL客户端/服务器通信协议<1> 协议类型:半双⼯。

<2> Mysql通常需要等所有的数据都已经发送给客户端才能释放这条查询所占⽤的资源。

<3> 在PHP函数中,mysql_query()会将整个查询的结果集缓存到内存中,⽽mysql_unbuffered_query()则不会缓存结果,直接从mysql服务器获取结果。

当结果集很⼤时,使⽤后者能减少内存的消耗,但服务器的资源会被这个查询占⽤⽐较长的时间。

3. 查询状态 可以使⽤命令来查询mysql当前查询的状态:show full processlist。

返回结果中的“State”键对应的值就表⽰查询的状态,主要有以下⼏种:<1> Sleep:线程正在等待客户端发送新的请求。

<2> Query:线程正在执⾏查询或正在将结果发送给客户端。

<3> Locked:在MySQL服务器层,该线程正在等待表锁。

(在没⾏锁的引擎出现)<4> Analyzing and statistics:线程正在收集存储引擎的统计信息,并⽣成查询的执⾏计划。

<5> Copying to tmp [on disk]:线程正在执⾏查询,并且将其结果集都复制到⼀个临时表中,这种状态要么是在做group by操作,要么是⽂件排序操作,或者是union操作。

MySQL中的查询优化与分页策略选择

MySQL中的查询优化与分页策略选择

MySQL中的查询优化与分页策略选择MySQL是目前最为流行的关系型数据库管理系统之一,广泛应用于各种互联网应用以及企业级软件系统中。

在实际项目中,查询性能的优化和分页策略的选择是数据库设计和开发的重要环节。

本文将从MySQL的查询优化和分页策略两个方面展开讨论。

一、查询优化1. 编写高效的SQL语句高效的SQL语句是查询优化的基础。

通过遵循一些编写SQL的最佳实践,可以减少查询执行时间。

首先,需要避免不必要的联接。

在编写SQL语句时,只选取必要的字段,并使用JOIN或子查询等方式联接表,而不是返回整个表的所有列。

此外,合理使用索引也是提高查询性能的重要因素。

2. 使用适当的索引索引是MySQL查询优化中的关键因素。

通过为经常被查询的列添加索引,可以大大加快查询速度。

使用EXPLAIN语句可以分析SQL语句的执行计划,根据分析的结果判断是否需要增加或优化索引。

需要注意的是,索引并不是越多越好,过多的索引会增加写操作的开销。

因此,在添加索引时要进行权衡,避免过度索引。

3. 慎重使用子查询子查询可以帮助我们实现复杂的查询逻辑,但是过多或者不必要的子查询会造成查询性能下降。

对于一些简单的查询,可以考虑使用JOIN语句替代子查询,以提高查询效率。

4. 分批处理大数据量查询当需要处理大数据量的查询时,如果一次性查询所有数据,可能会造成内存溢出或者查询时间过长的问题。

可以考虑使用分批查询的方式,每次查询一定数量的数据,并根据需求进行处理,从而降低系统负载并提高查询效率。

二、分页策略选择在Web应用中,分页是一个常见的功能需求。

MySQL提供了多种分页策略来满足不同场景下的需求。

下面介绍几种常用的分页策略。

1. LIMIT分页LIMIT语句是MySQL中最简单的分页方式。

通过设置OFFSET和LIMIT关键字,可以限制查询结果返回的起始位置和数量。

例如,SELECT * FROM table LIMIT 10 OFFSET 20; 表示从第21行开始查询10行数据,用于实现分页功能。

基于MySQL的数据库查询性能优化

基于MySQL的数据库查询性能优化

Keywords: MySQL;database;optimization;index;cache;paging
MySQL 是 现 今 最 流 行 的 开 源 关 系 型 数 据 库 ,
能体现在数据库的响应时间上,过多的重复查询以
MySQL+PHP 的开发环境是使用最广泛的 Web 应用
及耗时过长的操作会影响数据库的性能。而数据库
的处理速度上。随着应用程序的使用,数据逐渐增
验度,缩短 Web 应用的响应时间并避免对其他应用
[1]
其明显 ,一个应用的吞吐量瓶颈往往出现在数据库
多,数据库的查询压力也逐渐增大。查询语句的性
收稿日期:2020-07-17
可提高数据库的响应速度,进而提高应用的用户体
组件的影响 [2]。
稿件编号:202007113
次向 Pic 表中插入 3 万条和 30 万条数据,分别进行条
件 为 date 字 段 值 是 2019-11-11 的 查 询 测 试 ,结 果
如表 2 所示。
表2
数据量/条
3 000
图片描述
上传用户名
2 索引的使用
索引是从数据中提取的具有标识性的关键字,
并且包含对应数据的映射关系,为特定的数据库字
0.876 840 50
0.000 635 50
0.000 663 00
由表 2 可知,Pic 表有 3 万条数据量时,不带索引
与 带 索 引 的 数 据 库 响 应 时 间 分 别 是 0.138 671 s 和
0.000 701 5 s,带索引的响应速度是不带索引的 197
倍;表中包含 30 万条数据量时,不带索引与带索引的
宋永鹏
基于 MySQL 的数据库查询性能优化

(转)优化GroupBy--MYSQL一次千万级连表查询优化

(转)优化GroupBy--MYSQL一次千万级连表查询优化

(转)优化GroupBy--MYSQL⼀次千万级连表查询优化概述:交代⼀下背景,这算是⼀次项⽬经验吧,属于公司⼀个已上线平台的功能,这算是离职⼈员挖下的坑,随着数据越来越多,原本的SQL查询变得越来越慢,⽤户体验特别差,因此SQL优化任务交到了我⼿上。

这个SQL查询关联两个数据表,⼀个是攻击IP⽤户表主要是记录IP的信息,如第⼀次攻击时间,地址,IP等等,⼀个是IP攻击次数表主要是记录每天IP攻击次数。

⽽需求是获取某天攻击IP信息和次数。

(以下SQL语句测试均在测试服务器上上,正式服务器的性能好,查询时间快不少。

)准备:查看表的⾏数:未优化前SQL语句为:SELECTattack_ip,country,province,city,line,info_update_time AS attack_time,sum( attack_count ) AS attack_timesFROM`blacklist_attack_ip`INNER JOIN `blacklist_ip_count_date` ON `blacklist_attack_ip`.`attack_ip` = `blacklist_ip_count_date`.`ip`WHERE`attack_count` > 0AND `date` BETWEEN '2017-10-13 00:00:00'AND '2017-10-13 23:59:59'GROUP BY`ip`LIMIT 10 OFFSET 1000123456789101112131415161718先EXPLAIN分析⼀下:这⾥看到索引是有的,但是IP攻击次数表blacklist_ip_count_data也⽤上了临时表。

那么这SQL不优化直接第⼀次执⾏需要多久(这⾥强调第⼀次是因为MYSQL带有缓存功能,执⾏过⼀次的同样SQL,第⼆次会快很多。

MySQL之selectin子查询优化的实现

MySQL之selectin子查询优化的实现

MySQL之selectin⼦查询优化的实现下⾯的演⽰基于MySQL5.7.27版本⼀、关于MySQL⼦查询的优化策略介绍:⼦查询优化策略对于不同类型的⼦查询,优化器会选择不同的策略。

1. 对于 IN、=ANY ⼦查询,优化器有如下策略选择:semijoinMaterializationexists2. 对于 NOT IN、<>ALL ⼦查询,优化器有如下策略选择:Materializationexists3. 对于 derived 派⽣表,优化器有如下策略选择:derived_merge,将派⽣表合并到外部查询中(5.7 引⼊);将派⽣表物化为内部临时表,再⽤于外部查询。

注意:update 和 delete 语句中⼦查询不能使⽤ semijoin、materialization 优化策略⼆、创建数据进⾏模拟演⽰为了⽅便分析问题先建两张表并插⼊模拟数据:CREATE TABLE `test02` (`id` int(11) NOT NULL,`a` int(11) DEFAULT NULL,`b` int(11) DEFAULT NULL,PRIMARY KEY (`id`),KEY `a` (`a`)) ENGINE=InnoDB;drop procedure idata;delimiter ;;create procedure idata()begindeclare i int;set i=1;while(i<=10000)doinsert into test02 values(i, i, i);set i=i+1;end while;end;;delimiter ;call idata();create table test01 like test02;insert into test01 (select * from test02 where id<=1000)三、举例分析SQL实例⼦查询⽰例:SELECT * FROM test01 WHERE test01.a IN (SELECT test02.b FROM test02 WHERE id < 10)⼤部分⼈可定会简单的认为这个 SQL 会这样执⾏:SELECT test02.b FROM test02 WHERE id < 10结果:1,2,3,4,5,6,7,8,9SELECT * FROM test01 WHERE test01.a IN (1,2,3,4,5,6,7,8,9);但实际上 MySQL 并不是这样做的。

mysql 调优 面试题

mysql 调优 面试题

mysql 调优面试题MySQL调优面试题MySQL是一种常用的数据库管理系统,它的性能优化对于提升数据库的效率和响应速度非常重要。

在MySQL的面试中,调优问题经常被提及。

本文将介绍一些常见的MySQL调优面试题,并给出相应的解答。

1. 什么是MySQL的优化?MySQL的优化是指通过改进配置、索引和查询语句等手段,提高MySQL数据库系统的性能、稳定性和可用性的过程。

优化的目标是减少资源占用,提高查询速度,提高并发性能,以及降低数据库的负载。

2. 怎样查看MySQL的性能瓶颈?常见的方法有:- 运行SHOW PROCESSLIST命令,查看当前的查询和连接情况,找出正在执行的耗时查询。

- 使用MySQL自带的性能监控工具,如MySQL Workbench、MySQL Enterprise Monitor等,收集和分析数据库性能指标。

- 使用第三方性能监控工具,如pt-query-digest、Percona Toolkit等,对慢查询日志进行分析,找出影响性能的SQL语句。

- 监控服务器的系统资源使用情况,如CPU、内存、磁盘IO等,找出瓶颈所在。

- 使用性能测试工具,如sysbench、TPC-H等,对数据库进行压力测试,发现性能瓶颈。

3. 如何优化MySQL的查询性能?以下是一些常用的查询性能优化方法:- 使用合适的索引,以加快查询的速度。

可以通过使用EXPLAIN命令来分析查询语句的执行计划,判断是否使用了正确的索引。

- 避免使用SELECT *,只查询需要的字段,减少数据的传输量。

- 优化复杂查询语句,尽量减少子查询的使用,使用JOIN语句等代替。

- 避免在WHERE子句中使用函数或计算,以免引起全表扫描。

- 对于频繁执行的查询,考虑使用缓存技术,如Memcached或Redis,将查询结果缓存起来。

- 分析和优化查询语句的执行计划。

4. 如何优化MySQL的表结构?以下是一些常用的表结构优化方法:- 根据业务需求设计合理的表结构,避免冗余字段和重复数据。

Mysql 多表联合查询效率分析及优化

Mysql 多表联合查询效率分析及优化

Mysql 多表联合查询效率分析及优化1. 笛卡尔积(交叉连接) 在MySQL中可以为CROSS JOIN或者省略CROSS即JOIN,或者使用',' 如:1.SELECT * FROM table1 CROSS JOIN table22.SELECT * FROM table1 JOIN table23.SELECT * FROM table1,table2由于其返回的结果为被连接的两个数据表的乘积,因此当有WHERE, ON或USING 条件的时候一般不建议使用,因为当数据表项目太多的时候,会非常慢。

一般使用LEFT [OUTER] JOIN或者RIGHT [OUTER] JOIN2. 内连接INNER JOIN 在MySQL中把INNER JOIN叫做等值连接,即需要指定等值连接条件在MySQL中CROSS和INNER JOIN被划分在一起。

join_table: table_reference [INNER | CROSS] JOIN table_factor [join_condition]3. MySQL中的外连接,分为左外连接和右连接,即除了返回符合连接条件的结果之外,还要返回左表(左连接)或者右表(右连接)中不符合连接条件的结果,相对应的使用NULL对应。

例子:user表:id | name———1 | libk2 | zyfon3 | daodaouser_action表:user_id | action—————1 | jump1 | jump2 | run4 | swimsql:1.select id, name, action from user as u2.left join user_action a on u.id = er_idresult:id | name | action——————————–1 | libk | jump ①1 | libk | kick ②1 | libk | jump ③2 | zyfon | run ④3 | daodao | null ⑤分析:注意到user_action中还有一个user_id=4, action=swim的纪录,但是没有在结果中出现,而user表中的id=3, name=daodao的用户在user_action中没有相应的纪录,但是却出现在了结果集中因为现在是left join,所有的工作以left为准.结果1,2,3,4都是既在左表又在右表的纪录,5是只在左表,不在右表的纪录工作原理:从左表读出一条,选出所有与on匹配的右表纪录(n条)进行连接,形成n条纪录(包括重复的行,如:结果1和结果3),如果右边没有与on条件匹配的表,那连接的字段都是null.然后继续读下一条。

如何在MySQL中追踪和调试SQL语句执行过程

如何在MySQL中追踪和调试SQL语句执行过程

如何在MySQL中追踪和调试SQL语句执行过程引言MySQL是一种常用的关系型数据库管理系统,广泛应用于各类应用程序开发中。

在开发过程中,我们经常需要对SQL语句进行调试和优化,以提高查询性能和减少潜在的问题。

本文将介绍如何在MySQL中追踪和调试SQL语句执行过程的方法。

一、MySQL查询执行过程概述在深入了解如何追踪和调试SQL语句之前,我们先来了解一下MySQL查询执行的基本过程。

当我们执行一条SQL语句时,MySQL会经历以下几个主要阶段:1. 语法解析和语义检查:MySQL首先对SQL语句进行解析,并进行语法和语义检查,确保语句的正确性和合法性。

2. 查询优化:MySQL会根据查询的复杂性、表的结构以及索引等因素,选择最优的执行计划。

优化的目标是尽可能减少磁盘I/O操作和CPU计算,提高查询性能。

3. 执行计划生成和执行:MySQL会生成执行计划,决定如何访问和处理相关表中的数据。

然后,MySQL根据执行计划执行查询,并返回结果。

二、追踪SQL语句执行过程的方法在开发和调试过程中,我们通常需要了解SQL语句是如何被执行的,以便发现潜在的问题和优化查询性能。

下面介绍几种在MySQL中追踪SQL语句执行过程的方法:1. EXPLAIN命令:EXPLAIN命令是MySQL提供的一个非常有用的工具,用于分析查询语句的执行计划。

我们可以通过执行"EXPLAIN SELECT * FROMtable_name"来查看执行计划,并了解MySQL是如何执行查询的。

执行EXPLAIN命令后,MySQL会返回一个包含详细执行计划的结果集。

这些信息包括所使用的索引、表的读取方式、数据的访问顺序等。

通过分析执行计划,我们可以判断查询是否进行了索引扫描、是否存在全表扫描等问题,从而优化查询。

2. 慢查询日志:MySQL的慢查询日志是记录执行时间超过一定阈值的SQL语句的日志。

我们可以通过设置"slow_query_log"参数启用慢查询日志,并设置"long_query_time"参数指定执行时间的阈值。

记一次mysql千万订单汇总查询优化

记一次mysql千万订单汇总查询优化

记⼀次mysql千万订单汇总查询优化正⽂公司订单系统每⽇订单量庞⼤,有很多表数据超千万。

公司SQL优化这块做的很不好,可以说是没有做,所以导致查询很慢。

节选某个功能中的⼀句SQL EXPLAIN查看执⾏计划,EXPLAIN + SQL 查看SQL执⾏计划⼀个索引没⽤到,受影响⾏接近2000万,难怪会慢。

原来的SQL打印出来估计有好⼏张A4纸,我发个整理后的简版。

SELECT COUNT(t.w_order_id) lineCount, SUM(ROUND(t.feel_total_money / 100, 2)) AS lineTotalFee, SUM(ROUND(t.feel_fact_money / 100, 2)) AS lineFactFeeFROM w_orders_his tWHERE 1=1 AND DATE_FORMAT(t.create_time, '%Y-%m-%d') >= STR_TO_DATE(#{beginTime},'%Y-%m-%d') AND DATE_FORMAT(t.create_time, '%Y-%m-%d') <= STR_TO_DATE(#{endTime},'%Y-%m-%d') AND t.pay_state = #{payState} AND t.store_id LIKE '%#{storeId}%' limit 0,10这条sql需求是在两千万的表中捞出指定时间和条件的订单进⾏总数总⾦额汇总处理。

优化sql需要根据公司的业务,技术的架构等,且针对不同业务每条SQL的优化都是有差异的。

优化点1:AND DATE_FORMAT(t.create_time, '%Y-%m-%d') >= STR_TO_DATE(#{beginTime},'%Y-%m-%d')AND DATE_FORMAT(t.create_time, '%Y-%m-%d') <= STR_TO_DATE(#{endTime},'%Y-%m-%d')我们知道sql中绝对要减少函数的使⽤,像左边DATE_FORMAT(t.create_time, '%Y-%m-%d') 是绝对禁⽌使⽤的,如果数据库有⼀百万数据那么就会执⾏⼀百万次函数,⾮常⾮常影响效率。

MySQL查询优化技术--索引

MySQL查询优化技术--索引

MySQL查询优化技术--索引MySQL Query Optimization Technology—Index殷 丽 徐海华 吴海涛(上海师范大学,上海,200234)摘 要:在分析了索引优点和代价的基础上,介绍了MySQL使用索引的方法,并指出根据实际情况选择合适类型的索引对查询的优化起着决定性的作用。

关键词:索引 查询 优化0 引言索引是提高查询速度的最重要的手段。

虽然还有其它的一些技术可供使用,但是一般来说引起最大性能差异的都是索引的正确使用。

当然,并不总是这样简单就可以解决问题的,因为优化技术本来就并非总是简单的。

1 索引的优点不带索引的表仅仅是一个无序的数据行集合。

例如创建一个表indextest:CREATE TABLE indextest (testID INT NOT NULL, testName V ARCHAR(16) NOT NULL);在表中有1000条数据,其中一条为(3 Name1)的数据,如果要在整个表中查找testID=3的该条数据,在不带索引的表中就必须检查表中的每个数据行看它的testID是否与目标值相匹配。

这会导致一次完全的数据表扫描,这个过程会很慢,如果一个很大的表只包含少量的符合条件的记录,那么效率会非常低。

如果在表的testID数据列上建立了索引,这个索引包含表中的每个数据行的条目,但是索引的条目是按照testID值排序的。

在查找时就直接扫描索引并找到了该条数据,而且不用再搜索比该索引值更大的数据,就可以结束查询操作。

因此使用索引获得的功效是:找到了匹配的数据行在哪儿终止,并能够忽略其它的数据行;另一个功效来自使用定位算法查找第一条匹配的条目,而不需要从索引头开始执行线性扫描(例如,二分搜索就比线性扫描要快一些)。

通过使用这种方法,可以快速地定位第一个匹配的值,节省了大量的搜索时间。

数据库使用了多种技术来快速地定位索引值。

当运行涉及多表联结(jion)查询的时候,索引的价值就会更高。

MySQL巧用sum、case和when优化统计查询

MySQL巧用sum、case和when优化统计查询

MySQL巧⽤sum、case和when优化统计查询最近在公司做项⽬,涉及到开发统计报表相关的任务,由于数据量相对较多,之前写的查询语句查询五⼗万条数据⼤概需要⼗秒左右的样⼦,后来经过⽼⼤的指点利⽤sum,case...when...重写SQL性能⼀下⼦提⾼到⼀秒钟就解决了。

这⾥为了简洁明了的阐述问题和解决的⽅法,我简化⼀下需求模型。

现在数据库有⼀张订单表(经过简化的中间表),表结构如下:CREATE TABLE `statistic_order` (`oid` bigint(20) NOT NULL,`o_source` varchar(25) DEFAULT NULL COMMENT '来源编号',`o_actno` varchar(30) DEFAULT NULL COMMENT '活动编号',`o_actname` varchar(100) DEFAULT NULL COMMENT '参与活动名称',`o_n_channel` int(2) DEFAULT NULL COMMENT '商城平台',`o_clue` varchar(25) DEFAULT NULL COMMENT '线索分类',`o_star_level` varchar(25) DEFAULT NULL COMMENT '订单星级',`o_saledep` varchar(30) DEFAULT NULL COMMENT '营销部',`o_style` varchar(30) DEFAULT NULL COMMENT '车型',`o_status` int(2) DEFAULT NULL COMMENT '订单状态',`syctime_day` varchar(15) DEFAULT NULL COMMENT '按天格式化⽇期',PRIMARY KEY (`oid`)) ENGINE=InnoDB DEFAULT CHARSET=utf8项⽬需求是这样的:统计某段时间范围内每天的来源编号数量,其中来源编号对应数据表中的o_source字段,字段值可能为CDE,SDE,PDE,CSE,SSE。

如何在MySQL中处理大数据量的查询和过滤

如何在MySQL中处理大数据量的查询和过滤

如何在MySQL中处理大数据量的查询和过滤在MySQL中处理大数据量的查询和过滤引言在当今信息爆炸的时代,数据量呈指数级增长,处理大数据量的查询和过滤成为数据库管理中非常关键的一环。

MySQL作为一种常用的关系型数据库管理系统,我们需要掌握一些技巧和方法,以便在处理大数据量时能够高效地进行查询和过滤。

本文将从索引、分区、优化查询、并行处理等方面,详细介绍如何在MySQL中处理大数据量的查询和过滤。

一、索引的优化索引是提高查询性能的核心因素之一。

在处理大数据量时,充分利用索引能够减少磁盘I/O次数,加快查询速度。

以下是一些优化索引的方法:1. 设计合适的索引:根据实际应用中的查询需求,选择合适的列作为索引,可以通过对常用查询条件和连接条件进行分析,确定哪些列需要建立索引。

2. 避免过多的索引:虽然索引能够加快查询速度,但过多的索引也会增加写操作的成本。

需针对具体业务场景和数据模型,权衡哪些索引是必要的。

3. 使用覆盖索引:覆盖索引是一种特殊的索引,查询所需的列可以全部通过索引来获取,而不需要再回表查询数据行。

这样可以避免了额外的磁盘I/O操作,提高查询效率。

二、分区技术的应用分区技术是MySQL中处理大数据量的另一种重要手段。

将数据按照某种规则划分为多个分区,可以使查询在特定分区范围内进行,减少扫描数据的范围。

以下是一些分区技术的应用:1. 范围分区:将数据按照范围划分为不同的分区,常用于按照时间段对历史数据进行存储,比如按年份或按月份进行分区。

这样可以在查询时,只扫描特定时间范围内的分区,大大提高查询效率。

2. 列表分区:将数据按照固定的值进行分区,比如按地区进行分区。

这样可以将具有相似特征的数据放在同一个分区中,减少跨分区的查询。

3. 哈希分区:将数据按照哈希函数的结果进行分区,可以均匀地将数据分散到不同的分区中,提高负载均衡。

三、优化查询语句除了索引和分区技术外,优化查询语句也是提高查询性能的重要手段。

mysql中min和max查询优化

mysql中min和max查询优化

mysql中min和max查询优化mysql max() 函数的需扫描where条件过滤后的所有⾏:在测试环境中重现:测试版本:Server version: 5.1.58-log MySQL Community Server (GPL)testtable表中的索引mysql> show index from testtable;+-----------+------------+------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |+-----------+------------+------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+| testtable | 0 | PRIMARY | 1 | id | A | 2 | NULL | NULL | | BTREE | || testtable | 1 | key_number | 1 | number | A | 2 | NULL | NULL | YES | BTREE | |+-----------+------------+------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+对⽐的sql为:select sql_no_cache max(id) from testtable where number=98;select sql_no_cache id from testtable where number=98 order by id desc limit 1;查看执⾏计划:mysql> explain select sql_no_cache max(id) from testtable where number=98;+----+-------------+-----------+------+---------------+------------+---------+-------+------+--------------------------+| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |+----+-------------+-----------+------+---------------+------------+---------+-------+------+--------------------------+| 1 | SIMPLE | testtable | ref | key_number | key_number | 5 | const | 4 | Using where; Using index |+----+-------------+-----------+------+---------------+------------+---------+-------+------+--------------------------+1 row in set (0.00 sec)mysql> explain select sql_no_cache id from testtable where number=98 order by id desc limit 1;+----+-------------+-----------+------+---------------+------------+---------+-------+------+--------------------------+| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |+----+-------------+-----------+------+---------------+------------+---------+-------+------+--------------------------+| 1 | SIMPLE | testtable | ref | key_number | key_number | 5 | const | 4 | Using where; Using index |+----+-------------+-----------+------+---------------+------------+---------+-------+------+--------------------------+1 row in set (0.00 sec)执⾏计划显⽰完全⼀样。

MySQL百万级数据的4种查询优化方式

MySQL百万级数据的4种查询优化方式

MySQL百万级数据的4种查询优化⽅式⽬录⼀.limit越往后越慢的原因⼆.百万数据模拟1、创建员⼯表和部门表,编写存储过程插数据2.执⾏存储过程三.4种查询⽅式1.普通limit分页2.使⽤索引覆盖+⼦查询优化3.起始位置重定义4,降级策略(百度的做法)⼀.limit越往后越慢的原因当我们使⽤limit来对数据进⾏分页操作的时,会发现:查看前⼏页的时候,发现速度⾮常快,⽐如 limit 200,25,瞬间就出来了。

但是越往后,速度就越慢,特别是百万条之后,卡到不⾏,那这个是什么原理呢。

先看⼀下我们翻页翻到后⾯时,查询的sql是怎样的:select * from t_name where c_name1='xxx' order by c_name2 limit 2000000,25;这种查询的慢,其实是因为limit后⾯的偏移量太⼤导致的。

⽐如像上⾯的 limit 2000000,25 ,这个等同于数据库要扫描出2000025条数据,然后再丢弃前⾯的 20000000条数据,返回剩下25条数据给⽤户,这种取法明显不合理。

⼆.百万数据模拟1、创建员⼯表和部门表,编写存储过程插数据/*部门表,存在则进⾏删除 */drop table if EXISTS dep;create table dep(id int unsigned primary key auto_increment,depno mediumint unsigned not null default 0,depname varchar(20) not null default "",memo varchar(200) not null default "");/*员⼯表,存在则进⾏删除*/drop table if EXISTS emp;create table emp(id int unsigned primary key auto_increment,empno mediumint unsigned not null default 0,empname varchar(20) not null default "",job varchar(9) not null default "",mgr mediumint unsigned not null default 0,hiredate datetime not null,sal decimal(7,2) not null,comn decimal(7,2) not null,depno mediumint unsigned not null default 0);/* 产⽣随机字符串的函数*/DELIMITER $drop FUNCTION if EXISTS rand_string;CREATE FUNCTION rand_string(n INT) RETURNS VARCHAR(255)BEGINDECLARE chars_str VARCHAR(100) DEFAULT 'abcdefghijklmlopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';DECLARE return_str VARCHAR(255) DEFAULT '';DECLARE i INT DEFAULT 0;WHILE i < n DOSET return_str = CONCAT(return_str,SUBSTRING(chars_str,FLOOR(1+RAND()*52),1));SET i = i+1;END WHILE;RETURN return_str;END $DELIMITER;/*产⽣随机部门编号的函数*/DELIMITER $drop FUNCTION if EXISTS rand_num;CREATE FUNCTION rand_num() RETURNS INT(5)BEGINDECLARE i INT DEFAULT 0;SET i = FLOOR(100+RAND()*10);RETURN i;END $DELIMITER;/*建⽴存储过程:往emp表中插⼊数据*/DELIMITER $drop PROCEDURE if EXISTS insert_emp;CREATE PROCEDURE insert_emp(IN START INT(10),IN max_num INT(10))BEGINDECLARE i INT DEFAULT 0;/*set autocommit =0 把autocommit设置成0,把默认提交关闭*/SET autocommit = 0;REPEATSET i = i + 1;INSERT INTO emp(empno,empname,job,mgr,hiredate,sal,comn,depno) VALUES ((START+i),rand_string(6),'SALEMAN',0001,now(),2000,400,rand_num()); UNTIL i = max_numEND REPEAT;COMMIT;END $DELIMITER;/*建⽴存储过程:往dep表中插⼊数据*/DELIMITER $drop PROCEDURE if EXISTS insert_dept;CREATE PROCEDURE insert_dept(IN START INT(10),IN max_num INT(10))BEGINDECLARE i INT DEFAULT 0;SET autocommit = 0;REPEATSET i = i+1;INSERT INTO dep( depno,depname,memo) VALUES((START+i),rand_string(10),rand_string(8));UNTIL i = max_numEND REPEAT;COMMIT;END $DELIMITER;2.执⾏存储过程/*插⼊120条数据*/call insert_dept(1,120);/*插⼊500W条数据*/call insert_emp(0,5000000);插⼊500万条数据可能很慢三.4种查询⽅式1.普通limit分页/*偏移量为100,取25*/SELECT a.empno,a.empname,a.job,a.sal,b.depno,b.depnamefrom emp a left join dep b on a.depno = b.depno order by a.id desc limit 100,25;/*偏移量为4800000,取25*/SELECT a.empno,a.empname,a.job,a.sal,b.depno,b.depnamefrom emp a left join dep b on a.depno = b.depno order by a.id desc limit 4800000,25;执⾏结果[SQL]SELECT a.empno,a.empname,a.job,a.sal,b.depno,b.depnamefrom emp a left join dep b on a.depno = b.depno order by a.id desc limit 100,25;受影响的⾏: 0时间: 0.001s[SQL]SELECT a.empno,a.empname,a.job,a.sal,b.depno,b.depnamefrom emp a left join dep b on a.depno = b.depno order by a.id desc limit 4800000,25;受影响的⾏: 0时间: 12.275s越往后,查询效率越慢2.使⽤索引覆盖+⼦查询优化因为我们有主键id,并且在上⾯建了索引,所以可以先在索引树中找到开始位置的 id值,再根据找到的id值查询⾏数据。

MySQL数据库慢查询的排查与优化方法

MySQL数据库慢查询的排查与优化方法

MySQL数据库慢查询的排查与优化方法概述:MySQL是目前互联网应用中最常用的关系型数据库之一,然而,在实际的应用过程中,我们经常会遇到数据库查询变慢的情况。

这不仅影响了应用的性能和用户体验,还可能导致系统崩溃。

因此,对于MySQL数据库慢查询的排查和优化方法是非常重要的。

本文将为大家详细介绍如何有效地排查慢查询问题,并提供相应的优化建议。

一、初步排查问题当我们发现数据库查询变慢时,首先应该进行初步的排查,确定是否是数据库本身存在性能问题。

以下是一些初步排查问题的方法:1. 确认问题的范围:通过监控工具或日志分析,找出出现慢查询的具体时间段或具体的SQL语句,确认问题的范围。

2. 查看系统性能指标:通过监控工具查看MySQL实例的CPU、内存、磁盘IO等系统性能指标,确认是否存在明显的资源瓶颈,例如CPU使用率过高或磁盘IO过于频繁。

3. 检查数据库配置:检查MySQL的配置文件f,确认是否存在一些不合理的配置项,比如缓冲区设置过小、并发连接数设置过高等。

二、分析慢查询日志如果初步排查确定是数据库查询问题,那么接下来我们需要分析MySQL的慢查询日志,以找出导致查询变慢的具体原因。

下面是一些常用的方法和工具:1. 启用慢查询日志:在MySQL配置文件中开启慢查询日志(slow_query_log),并设置slow_query_log_file参数来指定日志文件的位置。

通常,建议将慢查询时间阈值设置为较小的值,例如1秒。

2. 分析慢查询日志:使用pt-query-digest、Percona Toolkit等工具对慢查询日志进行分析,以确定慢查询的原因和性能瓶颈。

- 查询频繁的SQL语句:通过分析慢查询日志中的SQL语句,可以找出查询频次最高的语句。

这些语句可能存在性能问题,需要优化。

- 查询缓慢的索引:通过慢查询日志可以找出执行查询语句时耗时较长的索引。

这些索引可能需要进行优化或重新设计。

- 锁等待和死锁情况:慢查询日志还可以展示出锁等待和死锁的情况。

数据库查询优化-20条必备sql优化技巧

数据库查询优化-20条必备sql优化技巧

数据库查询优化-20条必备sql优化技巧0、序⾔本⽂我们来谈谈项⽬中常⽤的 20 条 MySQL 优化⽅法,效率⾄少提⾼ 3倍!具体如下:1、使⽤ EXPLAIN 分析 SQL 语句是否合理使⽤ EXPLAIN 判断 SQL 语句是否合理使⽤索引,尽量避免 extra 列出现:Using File Sort、Using Temporary 等。

2、必须被索引重要SQL必须被索引:update、delete 的 where 条件列、order by、group by、distinct 字段、多表 join 字段。

3、联合索引对于联合索引来说,如果存在范围查询,⽐如between、>、<等条件时,会造成后⾯的索引字段失效。

对于联合索引来说,要遵守最左前缀法则:举列来说索引含有字段 id、name、school,可以直接⽤ id 字段,也可以 id、name 这样的顺序,但是 name; school 都⽆法使⽤这个索引。

所以在创建联合索引的时候⼀定要注意索引字段顺序,常⽤的查询字段放在最前⾯。

4、强制索引必要时可以使⽤ force index 来强制查询⾛某个索引: 有的时候MySQL优化器采取它认为合适的索引来检索 SQL 语句,但是可能它所采⽤的索引并不是我们想要的。

这时就可以采⽤ forceindex 来强制优化器使⽤我们制定的索引。

5、⽇期时间类型对于⾮标准的⽇期字段,例如字符串的⽇期字段,进⾏分区裁剪查询时会导致⽆法识辨,依旧⾛全表扫描。

尽管 TIMESTAMEP 存储空间只需要 datetime 的⼀半,然⽽由于类型 TIMESTAMP 存在性能问题,建议你还是尽可能使⽤类型 DATETIME。

(TIMESTAMP ⽇期存储的上限为2038-01-19 03:14:07,业务⽤ TIMESTAMP 存在风险;)6、禁⽌使⽤ SELECT *SELECT 只获取必要的字段,禁⽌使⽤ SELECT *。

mysqlin语句子查询效率慢的优化技巧示例

mysqlin语句子查询效率慢的优化技巧示例

mysqlin语句⼦查询效率慢的优化技巧⽰例表结构如下,⽂章只有690篇。

⽂章表article(id,title,content)标签表tag(tid,tag_name)标签⽂章中间表article_tag(id,tag_id,article_id)其中有个标签的tid是135,查询标签tid是135的⽂章列表。

690篇⽂章,⽤以下的语句查询,奇慢:select id,title from article where id in(select article_id from article_tag where tag_id=135)其中这条速度很快:select article_id from article_tag where tag_id=135查询结果是五篇⽂章,id为428,429,430,431,432⽤下⾯sql来查⽂章也很快:select id,title from article where id in(428,429,430,431,432)解决⽅法:select id,title from article where id in(select article_id from (select article_id from article_tag where tag_id=135) as tbt)其它解决⽅法:(举例)mysql> select * from abc_number_prop where number_id in (select number_id from abc_number_phone where phone = '82306839');为了节省篇幅,省略了输出内容,下同。

67 rows in set (12.00 sec)只有67⾏数据返回,却花了12秒,⽽系统中可能同时会有很多这样的查询,系统肯定扛不住。

⽤desc看⼀下(注:explain也可) mysql> desc select * from abc_number_prop where number_id in (select number_id from abc_number_phone where phone = '82306839');+----+--------------------+------------------+--------+-----------------+-------+---------+------------+---------+--------------------------+| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |+----+--------------------+------------------+--------+-----------------+-------+---------+------------+---------+--------------------------+| 1 | PRIMARY | abc_number_prop | ALL | NULL | NULL | NULL | NULL | 2679838 | Using where || 2 | DEPENDENT SUBQUERY | abc_number_phone | eq_ref | phone,number_id | phone | 70 | const,func | 1 | Using where; Using index |+----+--------------------+------------------+--------+-----------------+-------+---------+------------+---------+--------------------------+2 rows in set (0.00 sec)可以看出,在执⾏此查询时会扫描两百多万⾏,难道是没有创建索引吗,看⼀下mysql>show index from abc_number_phone;+------------------+------------+-------------+--------------+-----------------+-----------+-------------+----------+--------+------+------------+---------+---------------+| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | +------------------+------------+-------------+--------------+-----------------+-----------+-------------+----------+--------+------+------------+---------+---------------+| abc_number_phone | 0 | PRIMARY | 1 | number_phone_id | A | 36879 | NULL | NULL | | BTREE | | || abc_number_phone | 0 | phone | 1 | phone | A | 36879 | NULL | NULL | | BTREE | | || abc_number_phone | 0 | phone | 2 | number_id | A | 36879 | NULL | NULL | | BTREE | | || abc_number_phone | 1 | number_id | 1 | number_id | A | 36879 | NULL | NULL | | BTREE | | || abc_number_phone | 1 | created_by | 1 | created_by | A | 36879 | NULL | NULL | | BTREE | | || abc_number_phone | 1 | modified_by | 1 | modified_by | A | 36879 | NULL | NULL | YES | BTREE | | |+------------------+------------+-------------+--------------+-----------------+-----------+-------------+----------+--------+------+------------+---------+---------------+6 rows in set (0.06 sec)mysql>show index from abc_number_prop;+-----------------+------------+-------------+--------------+----------------+-----------+-------------+----------+--------+------+------------+---------+---------------+| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | +-----------------+------------+-------------+--------------+----------------+-----------+-------------+----------+--------+------+------------+---------+---------------+| abc_number_prop | 0 | PRIMARY | 1 | number_prop_id | A | 311268 | NULL | NULL | | BTREE | | || abc_number_prop | 1 | number_id | 1 | number_id | A | 311268 | NULL | NULL | | BTREE | | || abc_number_prop | 1 | created_by | 1 | created_by | A | 311268 | NULL | NULL | | BTREE | | || abc_number_prop | 1 | modified_by | 1 | modified_by | A | 311268 | NULL | NULL | YES | BTREE | | |+-----------------+------------+-------------+--------------+----------------+-----------+-------------+----------+--------+------+------------+---------+---------------+4 rows in set (0.15 sec)从上⾯的输出可以看出,这两张表在number_id字段上创建了索引的。

mysql优化limit查询语句的5个方法

mysql优化limit查询语句的5个方法

mysql优化limit查询语句的5个⽅法mysql的分页⽐较简单,只需要limit offset,length就可以获取数据了,但是当offset和length⽐较⼤的时候,mysql明显性能下降1.⼦查询优化法先找出第⼀条数据,然后⼤于等于这条数据的id就是要获取的数据缺点:数据必须是连续的,可以说不能有where条件,where条件会筛选数据,导致数据失去连续性,具体⽅法请看下⾯的查询实例:复制代码代码如下:mysql> set profiling=1;Query OK, 0 rows affected (0.00 sec)mysql> select count(*) from Member;+----------+| count(*) |+----------+| 169566 |+----------+1 row in set (0.00 sec)mysql> pager grep !~-PAGER set to 'grep !~-'mysql> select * from Member limit 10, 100;100 rows in set (0.00 sec)mysql> select * from Member where MemberID >= (select MemberID from Member limit 10,1) limit 100;100 rows in set (0.00 sec)mysql> select * from Member limit 1000, 100;100 rows in set (0.01 sec)mysql> select * from Member where MemberID >= (select MemberID from Member limit 1000,1) limit 100;100 rows in set (0.00 sec)mysql> select * from Member limit 100000, 100;100 rows in set (0.10 sec)mysql> select * from Member where MemberID >= (select MemberID from Member limit 100000,1) limit 100;100 rows in set (0.02 sec)mysql> nopagerPAGER set to stdoutmysql> show profiles\G*************************** 1. row ***************************Query_ID: 1Duration: 0.00003300Query: select count(*) from Member*************************** 2. row ***************************Query_ID: 2Duration: 0.00167000Query: select * from Member limit 10, 100*************************** 3. row ***************************Query_ID: 3Duration: 0.00112400Query: select * from Member where MemberID >= (select MemberID from Member limit 10,1) limit 100*************************** 4. row ***************************Query_ID: 4Duration: 0.00263200Query: select * from Member limit 1000, 100*************************** 5. row ***************************Query_ID: 5Duration: 0.00134000Query: select * from Member where MemberID >= (select MemberID from Member limit 1000,1) limit 100*************************** 6. row ***************************Query_ID: 6Duration: 0.09956700Query: select * from Member limit 100000, 100*************************** 7. row ***************************Query_ID: 7Duration: 0.02447700Query: select * from Member where MemberID >= (select MemberID from Member limit 100000,1) limit 100从结果中可以得知,当偏移1000以上使⽤⼦查询法可以有效的提⾼性能。

Mysql数据库千万级数据查询优化方案.....

Mysql数据库千万级数据查询优化方案.....

Mysql数据库千万级数据查询优化⽅案.....⼀,Mysql数据库中⼀个表⾥有⼀千多万条数据,怎么快速的查出第900万条后的100条数据?怎么查,谁能告诉我答案?有没有⼈想着,不就⼀条语句搞定嘛select * from table limit 9000000,100;那我们试试,去执⾏下这个SQL看看吧看见了吗,查了100条数据⽤了7.063s。

这能算的上是快速查询吗,估计没⼈能接受了这种速度吧!基于这个问题,我今天就要说说⼤数据时的快速查询了。

⾸先,我演⽰下⼤数据分页查询,我的test表⾥有1000多万条数据,然后使⽤limit进⾏分页测试:select * from test limit 0,100;耗时:0.005sselect * from test limit 1000,100;耗时:0.006sselect * from test limit 10000,100;耗时:0.013sselect * from test limit 100000,100;耗时:0.104sselect * from test limit 500000,100;耗时:0.395sselect * from test limit 1000000,100;耗时:0.823sselect * from test limit 5000000,100;耗时:3.909sselect * from test limit 10000000,100;耗时:10.761s我们发现⼀个现象,分页查询越靠后查询越慢。

这也让我们得出⼀个结论:1,limit语句的查询时间与起始记录的位置成正⽐。

2,mysql的limit语句是很⽅便,但是对记录很多的表并不适合直接使⽤。

对⼤数据量limit分页性能优化说到查询优化,我们⾸先想到的肯定是使⽤索引。

利⽤了索引查询的语句中如果条件只包含了那个索引列,那在这种情况下查询速度就很快了。

因为利⽤索引查找有相应的优化算法,且数据就在查询索引上⾯,不⽤再去找相关的数据地址了,这样节省了很多时间。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

下面的例子显示了如何为sampdb数据库的member数据表建立一个键缓存,该缓存的名称是member_cache,大小为1MB。执行这些指令的时候,你必须有超级(SUPER)权限。
1.建立一个足够容纳数据表索引的独立的缓存:
mysql&gt; SET GLOBAL member_cache.key_buffer_size = 1024*1024;
一般来说,当你执行管理员优化的时候,应该紧记以下规则:
· 访问内存中的数据快于访问磁盘上的数据。
· 尽量把数据保存在内存中可以减少磁盘操作。
· 保留索引中的信息比保留数据记录的内容更重要。
我们在后面将讨论如何应用这些规则。
增加服务器缓存的大小。服务器拥有很多参数(系统变量),你可以改变这些参数来影响服务器的操作。其中的几个参数直接地影响查询处理的速度。你可以改变的最重要的参数是数据表缓存的大小和存储引擎用于缓冲索引操作信息的缓存大小。如果你拥有可用的内存,就把它分配给服务器的缓存,以允许信息存储在内存中并减少磁盘操作。这会有很好的效果,因为访问内存中的信息比从磁盘读取信息的速度快得多。
2.给数据表指定键缓存:
mysql&gt; CACHE INDEX member IN member_cache;
+---------------+--------------------+----------+----------+
| Table | Op | Msg_type | Msg_text |
· MyISAM存储引擎使用键缓冲来保持与索引相关的操作的索引信息块。它的大小是由key_buffer_size系统变量控制的。这个值越大,MySQL就一次性在内存中保持更多的索引信息块,可以增加在内存中(而不用从磁盘上读取新的信息块)找到键值的可能性。键缓存的默认大小是8MB。如果你拥有很多的内存,这是一个很保守的值,你可以直接增加它的大小,并且会看到基于索引的检索、索引的建立和修改操作
如果需要检测某个服务器是否支持查询缓存,可以检查它的have_query_cache系统变量:
mysql&gt; SHOW VARIABLES LIKE ’have_query_cache’;
+------------------+-------+
| Variable_name | Value |
3.把数据表索引预先读入它的键缓存中:
mysql&gt; LOAD INDEX INTO CACHE member;
+---------------+--------------+----------+----------+
| Table | Op | Msg_type | Msg_text |
如果你很倚重MyISAM数据表,那么把它的键保存在内存中效果会很好,但是缓存中的争用却会导致相反的效果。从同一张表或不同的表读取数据都可能引起争用。你可以通过把键缓存设置成足以保存某个特定数据表的全部索引,从而避免同一张数据表的争用,但是其它数据表的键仍然需要争用缓存空间。
MySQL 4.1以上版本为这个问题提供了一种解决方案:它支持我们建立多个键缓存,并允许我们把某张数据表的索引指定并且预先装入某个缓存。如果你的数据表使用得很频繁,并且你有足够的内存,能够把它的索引载入缓存中,那么这种操作就是有用的。这种能力允许你同时避免同一张表和不同的表的争用:建立一个足够大的缓存,让它保存数据表的全部索引,并且指定该缓存专门用于那张数据表。在键被载入缓存之后,不在需要磁盘I/O操作。同时,键值永远不会被丢弃,对数据表的键的查看操作可以在内存中完成。
SHOW STATUS LIKE ’Opened_tables’;
Opened_tables显示了某个数据表必须打开的次数(因为它还没有打开)。这个值也显示为mysqladmin状态命令的输出信息中的 Opens值。如果这个数字是稳定的或缓慢增长,那么它的设置可能是正确的。如果这个数字增长得很快,就意味着这个缓存太小了,必须经常关闭数据表来为打开其它的数据表留出空间。如果你拥有文件描述信息,增加表缓存大小将减少数据表打开操作的数量。
保持授权表许可的简单性。尽管服务器在内存中缓存了授权表内容,但是如果你在tables_priv或columns_priv表中有一些数据行的话,服务器就必须为每个查询语句检查表层次和列层次的权限。如果这些表是空的,那么服务器就能优化自己的权限检查过程,略过这些层次。
如果你从源文件建立MySQL,那么就把它配置为使用静态类库,而不要使用共享类库。使用共享类库的动态二进制文件节约磁盘空间,然而静态二进制文件速度更快。但是,如果你使用了用户自定义函数(UDF)机制,那么有些系统要求使用动态链接。在这类系统上,静态二进制文件不能工作。
用于提高服务器的操作性能的其它一些策略还包括:
禁止不需要的存储引擎。服务器不会为禁止的引擎分配任何内存,因此我们可以利用这一点。如果从源文件建立MySQL,那么在配置的时候,大多数存储引擎就可以被排除在服务器之外。对于那些包含在服务器中的引擎来说,使用适当的启动选项可以在运行时禁止其中的大多数。
的性能有很大改善。
在MySQL 4.1以上版本中,你可以为MyISAM数据表建立附加的键缓存,并指定某些表使用它们。这样可以帮助提高这些数据表上的查询处理速度。
· InnoDB和BDB引擎拥有自己的用于缓冲数据和索引值的缓存。它们的大小是由innodb_buffer_pool_size和 bdb_cache_size变量控制的。InnoDB引擎还维护了一个日志缓冲。innodb_log_buffer_size变量可以控制它的大小。
+------------------+-------+
| have_query_cache | YES |
+------------------+-------+
对于那些支持查询缓存的服务器来说,缓存的操作是基于三个系统变量值的:
· query_cache_type决定查询缓存的操作模式。下表显示了可以使用的模式值:
例如,为了激活查询缓存并为它分配16MB内存,在配置文件中使用下面的设置:
· 不要在运行业务MySQL数据库的服务器上做调整参数的实验,最好建立一个独立的测试服务器。
· 为了大致了解哪种参数变量可能适合自己的系统,你可以查看MySQL发布文档中包含的f、f、my- f和f选项文件(在Unix系统上,你可以在源发布文件的支持文件目录和二进制发布文件的共享目录总找到这些文件。在Windows上,它们位于基本的安装目录中,其扩展名可能是.ini)。这些文件可能让你知道最好改变服务器上的那些参数以适应不同的使用层次,并且为这些参数提供了一些典型值。
如果你希望把其它的数据表载入同一个缓存中,或者为其它的数据表建立键缓存,上面的操作就足够了。
使用查询缓存
MySQL服务器可以使用查询缓存来提高那些重复执行的SELECT语句的
处理速度。它对性能的提高通常都是惊人的。查询缓存的工作方式如下所示:
模式 含义
0不要缓存查询结果或检索缓存的结果。
1缓存查询,除非它们以SELECT SQL_NO_CACHE开头。
2根据需要只缓存那些以SELECT SQL_CACHE开头的查询。
· query_cache_size决定分配给缓存的内存数量,单位是字节。
· query_cache_limit设置被缓存的最大结果集大小;比这个值大的查询结果不会被缓存。
· 当数据表被更新了之后,涉及到该数据表的任何缓存查询都变成无效的,并且会被丢弃。这可以防止服务器返回过期的结果。
在默认情况下,MySQL对查询缓存的支持是内建的。如果你不希望使用这种缓存,并且想避免它所导致的性能开销,可以使用--without-query-cache选项来运行配置脚本建立服务器。
· 另一个专用的缓存是查询缓存,我们在&quot;使用查询缓存&quot;部分中解释。
当你改变这些参数值的时候,应该遵循下面一些原则:
· 每次只改变一个参数。如果你一次改变多个相互独立的变量,那么就很难评估每种改变的效果了。
· 逐渐地增加系统变量值。根据理论,数量越多,性能越好,但是如果你使某个变量变得太大了,有可能造成系统资源匮乏,导致逆向效果,降低速度。
+---------------+--------------+----------+----------+
| sampdb.member | preload_keys | status | OK |+---------------+--------------+----------+----------+
前面的部分中讲解的优化措施都是没有特权的MySQL用户能够执行的。可以控制MySQL服务器或计算机的系统管理员能够执行额外的优化措施。例如,有些服务器参数附属于查询处理过程,并且是可以调整的,而且某些硬件配置因素对查询处理速度有直接的影响。在很多情况下,这些优化措施提高了整个服务器的性能,因此可以让所有的MySQL用户都受益。
使用MyISAM键缓存
当MySQL执行某个利用了MyISAM数
据表索引的语句的时候,它会使用键缓存来保持索引值。这种缓存减少了磁盘I/O:如果在缓存中找到了某个数据表需要的键值,就不需要再次从磁盘中读取。不幸的是,这种键缓存是有限的,并且在默认情况下,它是所有的MyISAM数据表共享使用的。如果在键缓存中没有找到键值并且键缓存是满的,争用将会导致:必须丢弃缓存中的某些值,为新值留出空间。如果下次需要那些已经被丢弃的值,就必须再次从磁盘上读取。
相关文档
最新文档