文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>SQL调优公式

SQL调优公式

时间:2010-07-06  来源:huangxifeng607

SQL调优公式T=S/V (此公式来源于互联网,本文只是引用)

S指sql所需处理的资源总量,V指sql单位时间所能处理的资 源量,T自然就是SQL执行所需时间了。

这个公式很简单,调优的目标是减少T,T=S/V,很简单的数学题,要减小值,那就只能是减小分 子,或者是增大分母了。那么调整的对象自然就要放到这里的S和V上,所以调优的方法就是围绕减少S和增大V。

增大V,在硬件设备不变、参 数不变的情况下,能控制的似乎不太多?
减少S(sql所需访问的资源总量),这通常是调优工作的重中之重,SQL调优的主要目的就是围绕着如何减 少S在进行。在Mysql里,我觉得就是减少rows值,一条SQL执行所读写的rows数直接影响到SQL的执行时间。

下面举一个我在 调优mysql查询的例子,需求是需要查出被点击数最大的16篇文章记录,sql如下:

mysql> select uid from test where status=1 order by today_hit desc limit 16;
+----------+
| uid |
+----------+
| 22380047 |
| 6264708 |
| 17318093 |
| 3412287 |
| 21542034 |
| 21542034 |
| 16929428 |
| 16929428 |
| 11994313 |
| 12234372 |
| 21938539 |
| 18323337 |
| 3441092 |
| 12234372 |
| 16758499 |
| 16929428 |
+----------+
16 rows in set (15.11 sec)

一个简单的查询需要15秒,我们看下它的执行计划

explain select uid from article_topic where status=1 order by today_hit desc limit 16;
+----+-------------+---------------+------+---------------+-------------+---------+-------+---------+-----------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------------+------+---------------+-------------+---------+-------+---------+-----------------------------+
| 1 | SIMPLE | test | ref | status_type | status_type | 1 | const | 2327024 | Using where; Using filesort |
+----+-------------+---------------+------+---------------+-------------+---------+-------+---------+-----------------------------+
1 row in set (0.00 sec)

这条sql需要扫描rows=2327024行,根据我们的公式,我们要减小S(sql所需访问的资源总量),即rows。

需要的 结果是today_hit即被点击最高的16篇文章,today_hit字段的类型为int,那么实际情况中会有很多点击数是0的情况,所以在加个条件 today_hit>0,把today_hit较小的值先排除,我们在看下执行计划:

mysql> explain select uid from test where status=1 and today_hit>0 order by today_hit desc limit 16;
+----+-------------+---------------+-------+-----------------------+-----------+---------+------+--------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------------+-------+-----------------------+-----------+---------+------+--------+-------------+
| 1 | SIMPLE | article_topic | range | today_hit,status_type | today_hit | 5 | NULL | 253220 | Using where |
+----+-------------+---------------+-------+-----------------------+-----------+---------+------+--------+-------------+
1 row in set (0.00 sec)

rows=253220,需要扫描的行数即我们公式里的S,比原来小了10倍,我们在来看看查询的结果。

mysql> select uid from test where status=1 and today_hit>0 order by today_hit desc limit 16;
+----------+
| uid |
+----------+
| 22380047 |
| 6264708 |
| 17318093 |
| 3412287 |
| 21542034 |
| 21542034 |
| 16929428 |
| 16929428 |
| 11994313 |
| 12234372 |
| 21938539 |
| 18323337 |
| 3441092 |
| 12234372 |
| 16758499 |
| 16929428 |
+----------+
16 rows in set (0.01 sec)

显然扫描200W行在进行排序,和扫描20W行在排序不是一个数量级别的。
时间比原来少不止100倍,查询结果和原来一样。当然 today_hit>0,这里什么数值比较合适,需要从你的实际情况定,需要保证需求的实现。

本例是通过加了一个条件,来减少S 值,在实际情况中,调优的方案肯定不止一种,但是万变不离其宗,最终的目的都是为了减少S,或者增大V,不过就Mysql本身来说,S的减少是很有潜力可 挖的,V相对困难一些吧。

排行榜 更多 +
辰域智控app

辰域智控app

系统工具 下载
网医联盟app

网医联盟app

运动健身 下载
汇丰汇选App

汇丰汇选App

金融理财 下载