您的位置:首页 > 产品设计 > UI/UE

mysql - 产品数量多的时候, 如何通过mysql的slow query log来处置

2011-11-21 23:25 429 查看
mysql服务器在运行的时候会维护几种日志文件,或者说生成吧.Slow Query Log只是其中之一.它主要是记录了执行时间超过一定时间(这个执行时间长短限额是mysql服务器的一个配置选项 -
long_query_time
)的SQL语句.以供开发人员或维护人员参考.要利用mysql的slow query log来解决问题,首先要知道它保存在哪里?哪个配置可以开关这个日志? 要打开mysql的slow query log开关,使之生成slow query log文件,可以向mysql的配置文件中(my.ini/my.cnf)添加如下配置

#To enable slow Query Log
log-slow-queries = /var/log/mysql/mysql-slow.log
long_query_time = 1

long_query_time配置选项设定了mysql服务器下sql语句执行的最长时间,超过这个时间的语句会被记录到slow query log日志文件中,但sql语句本身会继续执行而不会终止.


当然很多时候并没有这个需要,只是需要优化网站的速度时才需要查看,平时则关闭以获得最佳的性能.那么你还可以通过使用启动参数来临时开启这个功能.

mysqld --log-slow-queries=[日志文件路径]

如果参数后面没有指定日志文件路径,则会使用默认文件名,即主机名+-slow.log

首先需要说明的一点是,并不是这个日志文件中出现的sql语句就一定有问题或写的不对不好.只能说其中有一部分可以通过一些修改达到优化的目的.通常你可以针对符合下列条件的sql语句进行检查,看看能不能优化.

A) "Rows_examined" 超过2000

B) "Rows_examined" 虽然小于2000,但是一秒内执行超过20次

C) "Rows_examined" 比"Rows_sent"的3倍还大

上面的三个条件只是一个简单粗糙的标准,你要根据你的实际情况来确定.

首先应该针对符合条件的最坏的三到五条来检查.一旦确定了SQL语句,你可以通过EXPLAIN语句来重构这些SQL语句.

grep Rows_examined tmp/mysql_slow_queries/20111120-23.log  | sort -g -k9 -r |head -5

# Query_time: 2.914175 Lock_time: 0.000268 Rows_sent: 10 Rows_examined: 28530

# Query_time: 2.804642 Lock_time: 0.000295 Rows_sent: 10 Rows_examined: 28530

# Query_time: 6.682182 Lock_time: 0.205899 Rows_sent: 16 Rows_examined: 392

# Query_time: 1.579871 Lock_time: 0.000148 Rows_sent: 325 Rows_examined: 325

# Query_time: 2.669462 Lock_time: 0.728236 Rows_sent: 0 Rows_examined: 1

然后找出它所对应的SQL语句# Query_time: 6.379132 Lock_time: 0.265194 Rows_sent: 11 Rows_examined: 10551

grep -A 1 -B 2 10551 tmp/mysql_slow_queries/20111120-23.log

# Mon Nov 21 00:07:55 2011

# Query_time: 2.914175 Lock_time: 0.000268 Rows_sent: 10 Rows_examined: 28530

use xxxxxxxx;

SELECT 1 AS `status`, `e`.`entity_id`, `e`.`type_id`, `e`.`attribute_set_id`, `e`.`name`, `e`.`short_description`, `e`.`price`, `e`.`special_price`, `e`.`special_from_date`, `e`.`special_to_date`, `e`.`small_image`, `e`.`thumbnail`, `e`.`news_from_date`, `e`.`news_to_date`,
`e`.`url_key`, `e`.`required_options`, `e`.`image_label`, `e`.`small_image_label`, `e`.`thumbnail_label`, `e`.`created_at`, `e`.`msrp_enabled`, `e`.`msrp_display_actual_price_type`, `e`.`msrp`, `e`.`tax_class_id`, `e`.`price_type`, `e`.`weight_type`, `e`.`price_view`,
`e`.`shipment_type`, `e`.`links_purchased_separately`, `e`.`links_exist`, `e`.`is_imported`, `price_index`.`price`, `price_index`.`tax_class_id`, `price_index`.`final_price`, IF(price_index.tier_price IS NOT NULL, LEAST(price_index.min_price, price_index.tier_price),
price_index.min_price) AS `minimal_price`, `price_index`.`min_price`, `price_index`.`max_price`, `price_index`.`tier_price`, `cat_index`.`position` AS `cat_index_position` FROM `catalog_product_flat_1` AS `e`

INNER JOIN `catalog_product_index_price` AS `price_index` ON price_index.entity_id = e.entity_id AND price_index.website_id = '1' AND price_index.customer_group_id = 0

INNER JOIN `catalog_category_product_index` AS `cat_index` ON cat_index.product_id=e.entity_id AND cat_index.store_id='1' AND cat_index.visibility IN(2, 4) AND cat_index.category_id='2' ORDER BY rand() ASC LIMIT 10

--

# Mon Nov 21 00:52:51 2011

# Query_time: 2.804642 Lock_time: 0.000295 Rows_sent: 10 Rows_examined: 28530

use xxxxxxxx;

SELECT 1 AS `status`, `e`.`entity_id`, `e`.`type_id`, `e`.`attribute_set_id`, `e`.`name`, `e`.`short_description`, `e`.`price`, `e`.`special_price`, `e`.`special_from_date`, `e`.`special_to_date`, `e`.`small_image`, `e`.`thumbnail`, `e`.`news_from_date`, `e`.`news_to_date`,
`e`.`url_key`, `e`.`required_options`, `e`.`image_label`, `e`.`small_image_label`, `e`.`thumbnail_label`, `e`.`created_at`, `e`.`msrp_enabled`, `e`.`msrp_display_actual_price_type`, `e`.`msrp`, `e`.`tax_class_id`, `e`.`price_type`, `e`.`weight_type`, `e`.`price_view`,
`e`.`shipment_type`, `e`.`links_purchased_separately`, `e`.`links_exist`, `e`.`is_imported`, `price_index`.`price`, `price_index`.`tax_class_id`, `price_index`.`final_price`, IF(price_index.tier_price IS NOT NULL, LEAST(price_index.min_price, price_index.tier_price),
price_index.min_price) AS `minimal_price`, `price_index`.`min_price`, `price_index`.`max_price`, `price_index`.`tier_price`, `cat_index`.`position` AS `cat_index_position` FROM `catalog_product_flat_1` AS `e`

INNER JOIN `catalog_product_index_price` AS `price_index` ON price_index.entity_id = e.entity_id AND price_index.website_id = '1' AND price_index.customer_group_id = 0

INNER JOIN `catalog_category_product_index` AS `cat_index` ON cat_index.product_id=e.entity_id AND cat_index.store_id='1' AND cat_index.visibility IN(2, 4) AND cat_index.category_id='2' ORDER BY rand() ASC LIMIT 10

当然你有可能只会输出一条语句,这个时候你需要确定一下是哪个数据库,你可以通过下面的这条命令

grep -A 1 -B 10000 28530 tmp/mysql_slow_queries/20111120-23.log|grep -i ^use |tail -1


确定了数据库,你可以通过mysql控制台,使用EXPLAIN语句来分析对应的SQL语句,通过EXPLAIN的执行结果分析,看哪个表需要改进.通常是通过索引来改进一个查询的效率.当然具体的EXPLAIN的使用需要查询手册进一步了解.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: