mysql怎么查询快,mysql 加快查询速度
MySQL中如何查看“慢查询”,如何分析执行SQL的效率?
一、MySQL数据库有几个配置选项可以帮助我们及时捕获低效SQL语句\x0d\x0a\x0d\x0a1,slow_query_log\x0d\x0a这个参数设置为ON,可以捕获执行时间超过一定数值的SQL语句。\x0d\x0a\x0d\x0a2,long_query_time\x0d\x0a当SQL语句执行时间超过此数值时,就会被记录到日志中,建议设置为1或者更短。\x0d\x0a\x0d\x0a3,slow_query_log_file\x0d\x0a记录日志的文件名。\x0d\x0a\x0d\x0a4,log_queries_not_using_indexes\x0d\x0a这个参数设置为ON,可以捕获到所有未使用索引的SQL语句,尽管这个SQL语句有可能执行得挺快。\x0d\x0a\x0d\x0a二、检测mysql中sql语句的效率的方法\x0d\x0a\x0d\x0a1、通过查询日志\x0d\x0a(1)、Windows下开启MySQL慢查询\x0d\x0aMySQL在Windows系统中的配置文件一般是是my.ini找到[mysqld]下面加上\x0d\x0a代码如下\x0d\x0alog-slow-queries = F:/MySQL/log/mysqlslowquery。log\x0d\x0along_query_time = 2\x0d\x0a\x0d\x0a(2)、Linux下启用MySQL慢查询\x0d\x0aMySQL在Windows系统中的配置文件一般是是my.cnf找到[mysqld]下面加上\x0d\x0a代码如下\x0d\x0alog-slow-queries=/data/mysqldata/slowquery。log\x0d\x0along_query_time=2\x0d\x0a说明\x0d\x0alog-slow-queries = F:/MySQL/log/mysqlslowquery。\x0d\x0a为慢查询日志存放的位置,一般这个目录要有MySQL的运行帐号的可写权限,一般都将这个目录设置为MySQL的数据存放目录;\x0d\x0along_query_time=2中的2表示查询超过两秒才记录;\x0d\x0a\x0d\x0a2.show processlist 命令\x0d\x0a\x0d\x0aSHOW PROCESSLIST显示哪些线程正在运行。您也可以使用mysqladmin processlist语句得到此信息。\x0d\x0a各列的含义和用途:\x0d\x0aID列\x0d\x0a一个标识,你要kill一个语句的时候很有用,用命令杀掉此查询 /*/mysqladmin kill 进程号。\x0d\x0auser列\x0d\x0a显示单前用户,如果不是root,这个命令就只显示你权限范围内的sql语句。\x0d\x0ahost列\x0d\x0a显示这个语句是从哪个ip的哪个端口上发出的。用于追踪出问题语句的用户。\x0d\x0adb列\x0d\x0a显示这个进程目前连接的是哪个数据库。\x0d\x0acommand列\x0d\x0a显示当前连接的执行的命令,一般就是休眠(sleep),查询(query),连接(connect)。\x0d\x0atime列\x0d\x0a此这个状态持续的时间,单位是秒。\x0d\x0astate列\x0d\x0a显示使用当前连接的sql语句的状态,很重要的列,后续会有所有的状态的描述,请注意,state只是语句执行中的某一个状态,一个 sql语句,以查询为例,可能需要经过copying to tmp table,Sorting result,Sending data等状态才可以完成\x0d\x0ainfo列\x0d\x0a显示这个sql语句,因为长度有限,所以长的sql语句就显示不全,但是一个判断问题语句的重要依据。\x0d\x0a\x0d\x0a这个命令中最关键的就是state列,mysql列出的状态主要有以下几种:\x0d\x0aChecking table\x0d\x0a 正在检查数据表(这是自动的)。\x0d\x0aClosing tables\x0d\x0a 正在将表中修改的数据刷新到磁盘中,同时正在关闭已经用完的表。这是一个很快的操作,如果不是这样的话,就应该确认磁盘空间是否已经满了或者磁盘是否正处于重负中。\x0d\x0aConnect Out\x0d\x0a 复制从服务器正在连接主服务器。\x0d\x0a\x0d\x0aCopying to tmp table on disk\x0d\x0a 由于临时结果集大于tmp_table_size,正在将临时表从内存存储转为磁盘存储以此节省内存。\x0d\x0aCreating tmp table\x0d\x0a 正在创建临时表以存放部分查询结果。\x0d\x0adeleting from main table\x0d\x0a 服务器正在执行多表删除中的第一部分,刚删除第一个表。\x0d\x0adeleting from reference tables\x0d\x0a 服务器正在执行多表删除中的第二部分,正在删除其他表的记录。\x0d\x0a\x0d\x0aFlushing tables\x0d\x0a 正在执行FLUSH TABLES,等待其他线程关闭数据表。\x0d\x0aKilled\x0d\x0a 发送了一个kill请求给某线程,那么这个线程将会检查kill标志位,同时会放弃下一个kill请求。MySQL会在每次的主循环中检查kill标志位,不过有些情况下该线程可能会过一小段才能死掉。如果该线程程被其他线程锁住了,那么kill请求会在锁释放时马上生效。\x0d\x0aLocked\x0d\x0a 被其他查询锁住了。\x0d\x0aSending data\x0d\x0a 正在处理SELECT查询的记录,同时正在把结果发送给客户端。\x0d\x0a\x0d\x0aSorting for group\x0d\x0a 正在为GROUP BY做排序。\x0d\x0a Sorting for order\x0d\x0a 正在为ORDER BY做排序。\x0d\x0aOpening tables\x0d\x0a 这个过程应该会很快,除非受到其他因素的干扰。例如,在执ALTER TABLE或LOCK TABLE语句行完以前,数据表无法被其他线程打开。正尝试打开一个表。\x0d\x0aRemoving duplicates\x0d\x0a 正在执行一个SELECT DISTINCT方式的查询,但是MySQL无法在前一个阶段优化掉那些重复的记录。因此,MySQL需要再次去掉重复的记录,然后再把结果发送给客户端。\x0d\x0a\x0d\x0aReopen table\x0d\x0a 获得了对一个表的锁,但是必须在表结构修改之后才能获得这个锁。已经释放锁,关闭数据表,正尝试重新打开数据表。\x0d\x0aRepair by sorting\x0d\x0a 修复指令正在排序以创建索引。\x0d\x0aRepair with keycache\x0d\x0a 修复指令正在利用索引缓存一个一个地创建新索引。它会比Repair by sorting慢些。\x0d\x0aSearching rows for update\x0d\x0a 正在讲符合条件的记录找出来以备更新。它必须在UPDATE要修改相关的记录之前就完成了。\x0d\x0aSleeping\x0d\x0a 正在等待客户端发送新请求.\x0d\x0a\x0d\x0aSystem lock\x0d\x0a 正在等待取得一个外部的系统锁。如果当前没有运行多个mysqld服务器同时请求同一个表,那么可以通过增加--skip-external-locking参数来禁止外部系统锁。\x0d\x0aUpgrading lock\x0d\x0a INSERT DELAYED正在尝试取得一个锁表以插入新记录。\x0d\x0aUpdating\x0d\x0a 正在搜索匹配的记录,并且修改它们。\x0d\x0a\x0d\x0aUser Lock\x0d\x0a 正在等待GET_LOCK()。\x0d\x0aWaiting for tables\x0d\x0a 该线程得到通知,数据表结构已经被修改了,需要重新打开数据表以取得新的结构。然后,为了能的重新打开数据表,必须等到所有其他线程关闭这个表。以下几种情况下会产生这个通知:FLUSH TABLES tbl_name, ALTER TABLE, RENAME TABLE, REPAIR TABLE, ANALYZE TABLE,或OPTIMIZE TABLE。\x0d\x0awaiting for handler insert\x0d\x0a INSERT DELAYED已经处理完了所有待处理的插入操作,正在等待新的请求。\x0d\x0a 大部分状态对应很快的操作,只要有一个线程保持同一个状态好几秒钟,那么可能是有问题发生了,需要检查一下。\x0d\x0a 还有其他的状态没在上面中列出来,不过它们大部分只是在查看服务器是否有存在错误是才用得着。\x0d\x0a\x0d\x0a例如如图:\x0d\x0a\x0d\x0a3、explain来了解SQL执行的状态\x0d\x0aexplain显示了mysql如何使用索引来处理select语句以及连接表。可以帮助选择更好的索引和写出更优化的查询语句。\x0d\x0a使用方法,在select语句前加上explain就可以了:\x0d\x0a例如:\x0d\x0aexplain select surname,first_name form a,b where a.id=b.id\x0d\x0a结果如图\x0d\x0a\x0d\x0aEXPLAIN列的解释\x0d\x0atable\x0d\x0a显示这一行的数据是关于哪张表的\x0d\x0atype\x0d\x0a这是重要的列,显示连接使用了何种类型。从最好到最差的连接类型为const、eq_reg、ref、range、indexhe和ALL\x0d\x0apossible_keys\x0d\x0a显示可能应用在这张表中的索引。如果为空,没有可能的索引。可以为相关的域从WHERE语句中选择一个合适的语句\x0d\x0akey\x0d\x0a实际使用的索引。如果为NULL,则没有使用索引。很少的情况下,MYSQL会选择优化不足的索引。这种情况下,可以在SELECT语句 中使用USE INDEX(indexname)来强制使用一个索引或者用IGNORE INDEX(indexname)来强制MYSQL忽略索引\x0d\x0akey_len\x0d\x0a使用的索引的长度。在不损失精确性的情况下,长度越短越好\x0d\x0aref\x0d\x0a显示索引的哪一列被使用了,如果可能的话,是一个常数\x0d\x0arows\x0d\x0aMYSQL认为必须检查的用来返回请求数据的行数\x0d\x0aExtra\x0d\x0a关于MYSQL如何解析查询的额外信息。将在表4.3中讨论,但这里可以看到的坏的例子是Using temporary和Using filesort,意思MYSQL根本不能使用索引,结果是检索会很慢\x0d\x0a\x0d\x0aextra列返回的描述的意义\x0d\x0aDistinct\x0d\x0a一旦MYSQL找到了与行相联合匹配的行,就不再搜索了\x0d\x0aNot exists\x0d\x0aMYSQL优化了LEFT JOIN,一旦它找到了匹配LEFT JOIN标准的行,就不再搜索了\x0d\x0aRange checked for each Record(index map:#)\x0d\x0a没有找到理想的索引,因此对于从前面表中来的每一个行组合,MYSQL检查使用哪个索引,并用它来从表中返回行。这是使用索引的最慢的连接之一\x0d\x0aUsing filesort\x0d\x0a看到这个的时候,查询就需要优化了。MYSQL需要进行额外的步骤来发现如何对返回的行排序。它根据连接类型以及存储排序键值和匹配条件的全部行的行指针来排序全部行\x0d\x0aUsing index\x0d\x0a列数据是从仅仅使用了索引中的信息而没有读取实际的行动的表返回的,这发生在对表的全部的请求列都是同一个索引的部分的时候\x0d\x0aUsing temporary\x0d\x0a看到这个的时候,查询需要优化了。这里,MYSQL需要创建一个临时表来存储结果,这通常发生在对不同的列集进行ORDER BY上,而不是GROUP BY上\x0d\x0aWhere used\x0d\x0a使用了WHERE从句来限制哪些行将与下一张表匹配或者是返回给用户。如果不想返回表中的全部行,并且连接类型ALL或index,这就会发生,或者是查询有问题不同连接类型的解释(按照效率高低的顺序排序)\x0d\x0aconst\x0d\x0a表中的一个记录的最大值能够匹配这个查询(索引可以是主键或惟一索引)。因为只有一行,这个值实际就是常数,因为MYSQL先读这个值然后把它当做常数来对待\x0d\x0aeq_ref\x0d\x0a在连接中,MYSQL在查询时,从前面的表中,对每一个记录的联合都从表中读取一个记录,它在查询使用了索引为主键或惟一键的全部时使用\x0d\x0aref\x0d\x0a这个连接类型只有在查询使用了不是惟一或主键的键或者是这些类型的部分(比如,利用最左边前缀)时发生。对于之前的表的每一个行联合,全部记录都将从表中读出。这个类型严重依赖于根据索引匹配的记录多少—越少越好\x0d\x0arange\x0d\x0a这个连接类型使用索引返回一个范围中的行,比如使用或
成都创新互联公司专注于企业成都营销网站建设、网站重做改版、盐亭网站定制设计、自适应品牌网站建设、H5技术、商城网站定制开发、集团公司官网建设、外贸网站建设、高端网站制作、响应式网页设计等建站业务,价格优惠性价比高,为盐亭等各大城市提供网站开发制作服务。
回答于 2022-11-16
有什么方法mysql在1秒内快速查询百万条数据
有什么方法mysql在1秒内快速查询百万条数据1、应尽量避免在 where 子句中使用!=或操作符,否则将引擎放弃使用索引而进行全表扫描。2、对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。3、应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,
如何让mysql速度更快的响应?如何提高读取和查询速度
需要优化数据库语句,优化数据库表,还有数据分库分表操作。最主要是请求的缓存数据就可以更快了。最关键还是服务器得跟上。
希望我的回答可以帮到你,有什么不懂可以追问。
如何提高mysql查询速度
在已有的 MySQL 服务器之上使用 Apache Spark (无需将数据导出到 Spark 或者 Hadoop 平台上),这样至少可以提升 10 倍的查询性能。使用多个 MySQL 服务器(复制或者 Percona XtraDB Cluster)可以让我们在某些查询上得到额外的性能提升。你也可以使用 Spark 的缓存功能来缓存整个 MySQL 查询结果表。
思路很简单:Spark 可以通过 JDBC 读取 MySQL 上的数据,也可以执行 SQL 查询,因此我们可以直接连接到 MySQL 并执行查询。那么为什么速度会快呢?对一些需要运行很长时间的查询(如报表或者BI),由于 Spark 是一个大规模并行系统,因此查询会非常的快。MySQL 只能为每一个查询分配一个 CPU 核来处理,而 Spark 可以使用所有集群节点的所有核。在下面的例子中,我们会在 Spark 中执行 MySQL 查询,这个查询速度比直接在 MySQL 上执行速度要快 5 到 10 倍。
另外,Spark 可以增加“集群”级别的并行机制,在使用 MySQL 复制或者 Percona XtraDB Cluster 的情况下,Spark 可以把查询变成一组更小的查询(有点像使用了分区表时可以在每个分区都执行一个查询),然后在多个 Percona XtraDB Cluster 节点的多个从服务器上并行的执行这些小查询。最后它会使用map/reduce 方式将每个节点返回的结果聚合在一起形成完整的结果。
如何利用ClickHouse高速汇总查询MySQL数据
直连到MySQL的功能现在已被添加到ClickHouse中。所以可以直接从ClickHouse查询MySQL表中的数据。
ClickHouse是一个超高性能的海量数据快速查询的分布式实时处理平台,在数据汇总查询方面(如GROUP BY),ClickHouse的查询更快,因此通常情况下在MySQL上进行聚合。
下面是在自己的虚拟环境中做的测试记录。既然是虚拟环境非生产环境,请看参考应用级别,而不是严格的测试。
正确准备和测试大约1000万个数据项。
执行脚本以创建样本数据。这是约500 MB。
在MySQL中创建一个表并导入它。
由于似乎字符串数据比数字值更容易汇总,所以内容是数字的,但它们是可变的类型。
然后执行计算操作。
用BLOB类型做GROUPBY似乎很慢。
您可以在ClickHouse上使用MySQL数据,只需在下面的表格中指定它,而不是表名。
启动ClickHouse客户端并进行测试。
如果您在启动时不添加--multiline选项,则不会放置多行查询,因此请继续。
SELECT
data1,
COUNT(*)
FROM mysql('localhost','mikage','testdata','mikage','')
GROUP BY data1
┌─data1─┬─COUNT()─┐
│ 4│1999013│
│ 3│1998988│
│ 2│1999993│
│ 5│2001553│
│ 1│2000453│
└───────┴─────────┘
5 rows in set. Elapsed: 2.685 sec. Processed 10.00 million rows,40.00 MB(3.72 million rows/s.,14.90 MB/s.)
SELECT
data2,
COUNT(*)
FROM mysql('localhost','mikage','testdata','mikage','')
GROUP BY data2
┌─data2─┬─COUNT()─┐
│6 │ 999786│
│8 │1001805│
│9 │1001438│
│3 │1000357│
│2 │1000648│
│4 │ 998349│
│5 │ 998889│
│10 │ 999424│
│1 │1000530│
│7 │ 998774│
└───────┴─────────┘
10 rows in set. Elapsed: 2.692 sec. Processed 10.00 million rows,101.00 MB(3.71 million rows/s.,37.52 MB/s.)
SELECT
data3,
COUNT(*)
FROM mysql('localhost','mikage','testdata','mikage','')
GROUP BY data3
-- 结果省略
100000 rows in set. Elapsed: 5.236 sec. Processed 10.00 million rows,138.89 MB(1.91 million rows/s.,26.52 MB/s.)
SELECT
data1,
uniqExact(data5)
FROM mysql('localhost','mikage','testdata','mikage','')
GROUP BY data1
┌─data1─┬─uniqExact(data5)─┐
│ 4│ 1811674│
│ 3│ 1812072│
│ 2│ 1812503│
│ 5│ 1814106│
│ 1│ 1813005│
└───────┴──────────────────┘
5 rows in set. Elapsed: 12.944 sec. Processed 10.00 million rows,198.89 MB(772.55 thousand rows/s.,15.37 MB/s.)
-- ClickHouse有一个函数来粗略计算一个唯一的数字,所以让我们来计算一下。
在MySQL中,相当耗时的查询也可以在很短的时间内处理。
重复统计时,最好将数据复制到ClickHouse一次。
如果您复制它,后续查询将更快。
建议暂时使用StripeLog引擎。
如果您有一个主键,您可能还想要使用MergeTree表。这是在ClickHouse中最常用的引擎。
有必要用ORDER BY指定数据的排序顺序(即使有重复也没有问题)。
我会尝试以前的查询。以下是StripeLog引擎的测试结果。
测试耗时总结如下:
我认为这个错误很大,因为它在VM环境下仅测试了一次
从左边开始为,(1)MySQL中的时间 (2) ClickHouse从MySQL读取和处理数据的时间 (3) 在ClickHouse上处理复制数据的时间。
执行查询 MySQL处理时间 (秒) MySQL-ClickHouse处理时间 (秒) ClickHouse处理时间 (秒)
groupby(data1) 3.22 2.685 0.071
groupby(data2) 4.01 2.692 0.177
groupby(data3) 212.82 5.236 0.779
groupby(data1)+uniq(data5) 183.56 12.944 1.725
groupby(data1)+uniq(data5)概算 (无此功能) 6.026 0.285
当引用MySQL数据时,如果没有对应于ClickHouse的类型,它似乎是String类型。
没有相应的类型如Decimal类型,所以它也是String类型。
如果你想把它作为一个数值,精度将会改变,但是似乎有必要在MySQL端保持Double类型。
而且,Date和DateTime类型在MySQL和ClickHouse之间的范围也是不同的。
ClickHouse日期类型是1970 - 2038年之间。
如果有超出范围的数据,可能需要使其成为字符串类型,按年份,月份,日期分列,并将其作为数值复制。
参照源码如下:
MySQL类型 ClickHouse 类型 参考
tinyint UInt8 / Int8
smallint UInt16 / Int16
int / mediumint UInt32 / Int32
bigint UInt64 / Int64
float Float32
double Float64
dateDate 有可以表达的范围差异
datetime DateTime有可以表达的范围差异
timestamp DateTime
binaryFixed String
除上述以外 String
如何解决mysql 查询和更新速度慢
问题
我们有一个 SQL,用于找到没有主键 / 唯一键的表,但是在 MySQL 5.7 上运行特别慢,怎么办?
实验
我们搭建一个 MySQL 5.7 的环境,此处省略搭建步骤。
写个简单的脚本,制造一批带主键和不带主键的表:
执行一下脚本:
现在执行以下 SQL 看看效果:
...
执行了 16.80s,感觉是非常慢了。
现在用一下 DBA 三板斧,看看执行计划:
感觉有点惨,由于 information_schema.columns 是元数据表,没有必要的统计信息。
那我们来 show warnings 看看 MySQL 改写后的 SQL:
我们格式化一下 SQL:
可以看到 MySQL 将
select from A where A.x not in (select x from B) //非关联子查询
转换成了
select from A where not exists (select 1 from B where B.x = a.x) //关联子查询
如果我们自己是 MySQL,在执行非关联子查询时,可以使用很简单的策略:
select from A where A.x not in (select x from B where ...) //非关联子查询:1. 扫描 B 表中的所有记录,找到满足条件的记录,存放在临时表 C 中,建好索引2. 扫描 A 表中的记录,与临时表 C 中的记录进行比对,直接在索引里比对,
而关联子查询就需要循环迭代:
select from A where not exists (select 1 from B where B.x = a.x and ...) //关联子查询扫描 A 表的每一条记录 rA: 扫描 B 表,找到其中的第一条满足 rA 条件的记录。
显然,关联子查询的扫描成本会高于非关联子查询。
我们希望 MySQL 能先"缓存"子查询的结果(缓存这一步叫物化,MATERIALIZATION),但MySQL 认为不缓存更快,我们就需要给予 MySQL 一定指导。
...
可以看到执行时间变成了 0.67s。
整理
我们诊断的关键点如下:
\1. 对于 information_schema 中的元数据表,执行计划不能提供有效信息。
\2. 通过查看 MySQL 改写后的 SQL,我们猜测了优化器发生了误判。
\3. 我们增加了 hint,指导 MySQL 正确进行优化判断。
但目前我们的实验仅限于猜测,猜中了万事大吉,猜不中就无法做出好的诊断。
文章题目:mysql怎么查询快,mysql 加快查询速度
文章地址:http://pwwzsj.com/article/hcjceh.html