エントリが数十万の場合、limitステートメントのページングクエリで問題が発生します。上位のデータをクエリしても問題ありませんが、下位のデータが表示されると、非常に遅くなります。
要件:数百万行の大きなテーブルがあり、時間フィールドの順序に従ってページで読み取る必要があります。フィールドの順序が主キーIDの順序と一致していません。フィールドは次のようになります。大きなテーブルの場合、ページ付けのオンライン方法は主キーに基づいています。IDは順番にページングされるため、主キーIDの増分機能を使用して効果を実現できます。以下に示すように:
select * from table_name order by id asc limit 500000,10; //普通分页语句
//转换后的, 该语句查询非常快
select * from table_name where id > (select id from table_name order by id asc limit 500000,10) limit 10
ただし、この要件では、値が繰り返されるため、この機能を使用できないことは明らかです。
解決:
- まず、最初に時間フィールドにインデックスを追加する必要があります(フィールドの名前がcreate_timeであると想定)。インデックスを追加した後、制限0、10クエリは非常に高速ですが、制限500000、10クエリは低くなります。クエリはひどく遅く、通常は数秒かかります。Explainクエリプランでは、MySQLが最初の500,000行をスキャンした後、データを読み取る前に制限50000.10ステートメントが表示されることがわかるため、これは非常に低速です。
- ステップ1で最適化を続けます。
//对于几十万表基本都能在1s内查出来 select * from table_name where id in (SELECT id from (select id from table_name LIMIT 500000,10) as tmp) // 1.其中使用(SELECT id from (select id from table_name LIMIT 500000,10) as tmp) 这种繁琐的写法是为了适应mysql5.6不支持子查询语句中有limit操作.当然你也可以将上述语句拆分成 两条,先执行子查询获取id结果集, 然后在用id in id结果集语句获取最终结果也可. // 2.该句子主要时间花费在(SELECT id from (select id from table_name LIMIT 500000,10) as tmp) 子查询上, 而 id in的查询是非常快的,自己测试只要零点零几秒. // 3.最后要强调的是以上例子写法比较简化,查询只取出自己需要的列,不要列就不要取出,因为取出不需要的列 时,传送数据的时间会加大以及其他的一些开销,尤其是无用的列很多很大时. 所以select *写法要根据你 的业务需要调整,有时候这个方面的耗时还是很大的,一定引起重视.
ケーキソリューションのアイシング(特定のステートメントに対してのみキャッシュできるmysql独自のクエリキャッシュを使用)
使用条件:(まず、すでにmysqlクエリキャッシュを使用している場合、この部分は無視できます)最適化するクエリステートメントが基本的に同じである場合(一部の公開データ(ホームページなど))アプリケーションの場合、これらはキャッシュを再度クエリするだけでよく、同じクエリを直接使用できるため、速度が非常に速くなります。mysqlがクエリキャッシュの機能を提供することがあります。何ですか?キャッシュするだけで済みます。一部の特定のステートメントで、ステートメントを最適化する必要はありません。アプリケーション内のすべてのステートメントはクエリキャッシュを使用します。クエリにもコストがかかることを知っておくことが重要です。一部のステートメントでは、役に立たないか、速度が低下することさえあります。 。mqsqlは、指定されたステートメントのみのキャッシュもサポートし、他のステートメントは影響を受けない場合があります。
mysqlのクエリキャッシュの予備的な理解:
mysql的查询缓存功能由query_cache_type系统变量控制,有如下取值:
OFF:表示不开启查询
ON: 表示对所有语句都开启查询缓存, 除非sql语句以SELECT SQL_NO_CACHE开头明确表示不对该句子缓存
DEMAND: 当语句以select SQL_CACHE开头的才会缓存
コード
1.找到你的mysql配置文件在 [mysqld] 块下添加以下内容
[mysqld]
query_cache_type=2
2. 然后重启你的mysql服务, 进入mysql命令行,执行如下命令
show variables like "query_cache_type"; //再次确认下查询缓存是否开启
show variables like "query_cache_size"; //确认查询缓存大小,注意需要大于0
set global query_cache_size = 1048576 //设置查询缓存大小,可设置的值为1024倍数(单位byte)需要大于40k
3. 对于你要缓存的select语句使用 SELECT SQL_CACHE开头, 以下举个栗子:
SELECT SQL_CACHE * from table_name order by create_time desc limit 50000, 10;
当mysql看到SELECT SQL_CACHE开头时会去查询缓存中找有没有缓存过,没有则执行语句并将结果缓存起来以供后续相同的查询使用.