以下查询是否需要1分钟或更长时间才能完成?

时间:2013-08-14 18:02:36

标签: php mysql optimization query-optimization

以下查询使用80%或更多CPU,完成时间可能超过1分钟。 我的问题:我的查询是否有任何问题导致CPU使用情况如此?我可以通过优化MySQL服务器配置来减少CPU使用率和查询时间吗?

查询1(loan_history包含260万条记录)

SELECT officer, SUM(balance) as balance
FROM loan_history
WHERE bank_id = '1'
AND date ='2013-07-04'  
AND officer IS NOT NULL
AND officer <> ''
GROUP BY officer
ORDER BY officer;

查询2(loan_history包含260万条记录)

SELECT SUM(weighted_interest_rate) as total
FROM (SELECT balance, tmp1.balance_sum,
    (balance / tmp1.balance_sum * interest_rate) as weighted_interest_rate
    FROM loan_history,
(SELECT SUM(balance) balance_sum FROM loan_history
WHERE date = '2013-07-04'
    AND bank_id = '1') as tmp1
WHERE date = '2013-07-04'
AND bank_id = '1') tmp2

表格信息:

CREATE TABLE `loan_history` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`bank_id` int(11) DEFAULT NULL,
`loan_purpose_id` int(11) DEFAULT NULL,
`date` date NOT NULL,
`credit_grade` varchar(5) COLLATE utf8_unicode_ci DEFAULT NULL,
`interest_rate` decimal(5,2) NOT NULL,
`officer` varchar(5) COLLATE utf8_unicode_ci DEFAULT NULL,
`balance` decimal(10,2) NOT NULL,
`start_date` date DEFAULT NULL,
`days_delinquent` int(11) DEFAULT NULL,
 PRIMARY KEY (`id`),
 KEY `IDX_9F5FE3F11C8FB41` (`bank_id`),
 KEY `IDX_9F5FE3F6F593857` (`loan_purpose_id`),
 KEY `date` (`date`),
 KEY `credit_grade` (`credit_grade`),
 KEY `officer` (`officer`),
 KEY `start_date` (`start_date`),
 KEY `days_delinquent` (`days_delinquent`),
 KEY `interest_rate` (`interest_rate`),
 KEY `balance` (`balance`),
 CONSTRAINT `FK_9F5FE3F11C8FB41` FOREIGN KEY (`bank_id`) REFERENCES `bank` (`id`),
 CONSTRAINT `FK_9F5FE3F6F593857` FOREIGN KEY (`loan_purpose_id`) REFERENCES     `loan_purpose` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2630634 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

查询1 EXPLAIN:

| id | select_type | table        | type        | possible_keys                    | key                      | key_len | ref  | rows | Extra                                                                                   |

|  1 | SIMPLE      | loan_history | index_merge | IDX_9F5FE3F11C8FB41,date,officer | date,IDX_9F5FE3F11C8FB41 | 3,5     | NULL | 4829 | Using intersect(date,IDX_9F5FE3F11C8FB41); Using where; Using temporary; Using filesort |

查询2 EXPLAIN:

| id | select_type | table        | type        | possible_keys            | key                      | key_len | ref  | rows | Extra 

|  1 | PRIMARY     | <derived2>   | ALL         | NULL                     | NULL                     | NULL    | NULL | 8236 |

|  2 | DERIVED     | <derived3>   | system      | NULL                     | NULL                     | NULL    | NULL |    1 |                             

|  2 | DERIVED     | loan_history | index_merge | IDX_9F5FE3F11C8FB41,date | date,IDX_9F5FE3F11C8FB41 | 3,5     | NULL | 4829 | Using intersect(date,IDX_9F5FE3F11C8FB41); Using where; Using index |

|  3 | DERIVED     | loan_history | index_merge | IDX_9F5FE3F11C8FB41,date | date,IDX_9F5FE3F11C8FB41 | 3,5     | NULL | 4829 | Using intersect(date,IDX_9F5FE3F11C8FB41); Using where; Using index |

My.cnf文件:

default-storage-engine=MyISAM
interactive_timeout=300
key_buffer_size=256M
key_cache_block_size=4096
max_heap_table_size=128M
max_join_size=1000000000
max_allowed_packet=32M
open_files_limit=4096
query_cache_size=256M
query_cache_limit=10240M
query_cache_type=1
table_cache=256
thread_cache_size=100
tmp_table_size=128M
wait_timeout=7800
max_user_connections=50
join_buffer_size=256K
sort_buffer_size=4M
read_rnd_buffer_size=1M

innodb_open_files=300
innodb_log_file_size=256M
innodb_log_buffer_size=8M
innodb_file_per_table=1
innodb_additional_mem_pool_size=20M
innodb_flush_log_at_trx_commit=0
innodb_flush_method=O_DIRECT
innodb_support_xa=0
innodb_thread_concurrency=0
innodb_buffer_pool_size=3000M

2 个答案:

答案 0 :(得分:1)

第一个查询中的sum()GROUP BY可能需要一些时间,但我认为您无法在那里做很多事情。

在第二个查询中,您的FROM (SELECT....可能很难打到系统,我建议转向

(SELECT balance, tmp1.balance_sum, (balance / tmp1.balance_sum * interest_rate) as weighted_interest_rate FROM loan_history, (SELECT SUM(balance) balance_sum FROM loan_history WHERE date = '2013-07-04' AND bank_id = '1') as tmp1 WHERE date = '2013-07-04' AND bank_id = '1')

进入视图或弄清楚如何使用JOIN

答案 1 :(得分:0)

请告诉我们每个人的确做多少。每个超过1分钟并不是那么多指示性的。

如何,来自MySQL manual

  

调整MySQL服务器时,要配置的两个最重要的变量是key_buffer_size和table_cache。在尝试更改任何其他变量之前,您应首先确信您已正确设置这些设置。

另外,看看here

至于优化,首先尝试composite index