0

以下查询使用 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 解释:

| 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 解释:

| 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 |

我的.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
4

2 回答 2

1

第一个查询的sum()andGROUP 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

于 2013-08-14T18:06:03.010 回答
0

请告诉我们每个人到底需要多少。每个超过 1 分钟并没有那么大的指示性。

无论如何,来自MySQL 手册

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

另外,看看这里

至于优化,先试试复合索引

于 2013-08-14T18:43:29.623 回答