SugarCRM 慢查询(在 MySQL 上)
Posted
技术标签:
【中文标题】SugarCRM 慢查询(在 MySQL 上)【英文标题】:SugarCRM Slow Queries (on MySQL) 【发布时间】:2013-04-04 20:31:12 【问题描述】:我们将 SugarCRM 与 mysql 5.5 数据库一起使用,并且发现频繁出现的查询性能不佳。
很遗憾,由于 SugarCRM 的性质,无法重新排序查询。我已经尝试通过索引进行优化,但还没有走得很远。也就是说,我也不是很擅长这样做。
您能否建议任何替代索引来改善我们的结果并避免文件排序?
查询:
SELECT DISTINCT cases.id, cases.case_number, cases.status, cases.name,
cases.date_entered,
cases.assigned_user_id, cases.system_id
FROM cases
INNER JOIN team_sets_teams tst ON tst.team_set_id = cases.team_set_id
INNER JOIN team_memberships team_memberships ON tst.team_id = team_memberships.team_id
AND team_memberships.user_id = 'f09ab586-986c-a6f6-0c2e-4d1f1432b6ec'
AND team_memberships.deleted=0
ORDER BY cases.case_number DESC
LIMIT 0,11;
解释结果:
select_type table type possible_keys key ref rows Extra
SIMPLE team_memberships ref team_id,user_id,idx_team_membership idx_team_membership const 26 Using where; Using index; Using temporary; Using filesort
SIMPLE tst ref idx_ud_set_id,idx_ud_team_id,idx_ud_team_set_id idx_ud_team_id sugarcrm.team_memberships.team_id 7 Using where
SIMPLE cases ref idx_cases_tmst_id,idx_cases_created idx_cases_tmst_id sugarcrm.tst.team_set_id 5 Using where
表定义:
CREATE TABLE `cases` (
`id` char(36) NOT NULL,
`name` varchar(255) DEFAULT NULL,
`date_entered` datetime DEFAULT NULL,
`date_modified` datetime DEFAULT NULL,
`modified_user_id` char(36) DEFAULT NULL,
`created_by` char(36) DEFAULT NULL,
`description` text,
`deleted` tinyint(1) DEFAULT '0',
`assigned_user_id` char(36) DEFAULT NULL,
`team_id` char(36) DEFAULT NULL,
`case_number` int(11) NOT NULL AUTO_INCREMENT,
`type` varchar(255) DEFAULT NULL,
`status` varchar(100) DEFAULT NULL,
`priority` varchar(100) DEFAULT NULL,
`resolution` text,
`system_id` int(11) DEFAULT NULL,
`work_log` text,
`account_id` char(36) DEFAULT NULL,
`portal_viewable` tinyint(1) DEFAULT '0',
`team_set_id` char(36) DEFAULT NULL,
`parent_id` char(36) DEFAULT NULL,
`parent_type` varchar(255) DEFAULT 'Cases',
PRIMARY KEY (`id`),
UNIQUE KEY `casesnumk` (`case_number`),
UNIQUE KEY `case_number` (`case_number`,`system_id`),
KEY `idx_case_name` (`name`),
KEY `idx_account_id` (`account_id`),
KEY `idx_cases_stat_del` (`assigned_user_id`,`status`,`deleted`),
KEY `idx_cases_tmst_id` (`team_set_id`),
KEY `date_modified` (`date_modified`),
KEY `modified_user_id` (`modified_user_id`),
KEY `idx_cases_created` (`team_set_id`,`date_entered`),
KEY `team_id` (`team_id`),
KEY `idx_cases_del` (`deleted`),
KEY `idx_cases_date_entered` (`date_entered`),
KEY `idx_cases_status` (`status`),
KEY `idx_cases_parent_id` (`parent_id`),
KEY `idx_cases_priority` (`priority`)
) ENGINE=InnoDB
CREATE TABLE `team_sets_teams` (
`id` char(36) NOT NULL,
`team_set_id` char(36) DEFAULT NULL,
`team_id` char(36) DEFAULT NULL,
`date_modified` datetime DEFAULT NULL,
`deleted` tinyint(1) DEFAULT '0',
PRIMARY KEY (`id`),
KEY `idx_ud_set_id` (`team_set_id`,`team_id`),
KEY `idx_ud_team_id` (`team_id`),
KEY `idx_ud_team_set_id` (`team_set_id`),
KEY `idx_tst_deleted` (`deleted`)
) ENGINE=InnoDB
CREATE TABLE `team_memberships` (
`id` char(36) NOT NULL,
`team_id` char(36) DEFAULT NULL,
`user_id` char(36) DEFAULT NULL,
`explicit_assign` tinyint(1) DEFAULT '0',
`implicit_assign` tinyint(1) DEFAULT '0',
`date_modified` datetime DEFAULT NULL,
`deleted` tinyint(1) DEFAULT '0',
PRIMARY KEY (`id`),
KEY `date_modified` (`date_modified`),
KEY `team_id` (`team_id`),
KEY `user_id` (`user_id`),
KEY `idx_team_membership` (`user_id`,`team_id`,`deleted`)
) ENGINE=InnoDB
【问题讨论】:
所有 ID 都是CHAR(36)
s 的事实绝对没有帮助,特别是因为表使用的是 InnoDB
,但您可能无法更改它。可能可以添加一些索引来帮助这个特定的查询,但它们可能不会产生很大的不同。慢有多慢?
您说得对,我们无法改变这一点。通常,在具有大量 CPU 和 RAM 的服务器上查询需要 5 秒。但它经常被许多用户作为 dashlet 的一部分运行,并且应该能够在
你确定文件排序是 MySQL 花费最多时间的地方吗?您可以分析查询并使用这些结果更新您的问题吗?如果文件排序真的是瓶颈所在,我会感到惊讶。也就是说,SugarCRM 绝对不是为了高效而设计的。
这很有启发性。现在我必须弄清楚下一步该做什么。 starting 0.000015 ... Creating tmp table 0.000029 executing 0.000003 Copying to tmp table 0.891442 converting HEAP to MyISAM 0.498635 Copying to tmp table on disk 8.596956 Sorting result 0.287117 logging slow query 0.000002 logging slow query 0.000073 cleaning up 0.000006
查询速度变慢的是这个“ORDER BY cases.case_number DESC”。因此,您可以在 listviewdefs.php 的顶部添加检查是否有来自搜索表单的条件的功能。如果是这样,那么忽略它会很快,如果不是,添加 $_REQUEST['order_by'] = 'DO_NO_SORT'; .我希望这会为您解决问题。这是 SugarCRM 的一款非常糟糕的产品,不适合大数据。
【参考方案1】:
从 Ubuntu 10.04 服务器切换到 12.04 时,我遇到了类似的问题。因为 InnoDB 作为 Ubuntu 12.04 中打包的较新 MySQL 版本的默认引擎。我对 MySQL 服务器设置进行了一些尝试,例如 query_cache_size、innodb_buffer_pool_size、innodb_log_buffer_size,它显着提高了性能。
【讨论】:
我增加了 RAM 和许多调整选项以减少写入 temp 的需要,但这似乎是一场失败的战斗,作为连接的一部分返回了太多行。 @user2246576 如果是这种情况,并且更改设置不会阻止复制到临时表,那么您唯一的选择似乎是升级您的服务器以使用 SSD 以最小化您的读写次。除非您想尝试修改 SugarCRM 核心...【参考方案2】:尝试以下索引:
mysql> show indexes from team_memberships;
+------------------+------------+------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+------------------+------------+------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| team_memberships | 0 | PRIMARY | 1 | id | A | 665 | NULL | NULL | | BTREE | | |
| team_memberships | 1 | idx_team_membership | 1 | user_id | A | 665 | NULL | NULL | YES | BTREE | | |
| team_memberships | 1 | idx_team_membership | 2 | team_id | A | 665 | NULL | NULL | YES | BTREE | | |
| team_memberships | 1 | idx_teammemb_team_user | 1 | team_id | A | 665 | NULL | NULL | YES | BTREE | | |
| team_memberships | 1 | idx_teammemb_team_user | 2 | user_id | A | 665 | NULL | NULL | YES | BTREE | | |
| team_memberships | 1 | idx_team_deleted_user | 1 | user_id | A | 665 | NULL | NULL | YES | BTREE | | |
| team_memberships | 1 | idx_team_deleted_user | 2 | deleted | A | 665 | NULL | NULL | YES | BTREE | | |
| team_memberships | 1 | idx_team_deleted_user | 3 | team_id | A | 665 | NULL | NULL | YES | BTREE | | |
+------------------+------------+------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
mysql> show indexes from cases;
+-------+------------+--------------------+--------------+------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------+------------+--------------------+--------------+------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| cases | 0 | PRIMARY | 1 | id | A | 6 | NULL | NULL | | BTREE | | |
| cases | 0 | casesnumk | 1 | case_number | A | 6 | NULL | NULL | | BTREE | | |
| cases | 0 | case_number | 1 | case_number | A | 6 | NULL | NULL | | BTREE | | |
| cases | 0 | case_number | 2 | system_id | A | 6 | NULL | NULL | YES | BTREE | | |
| cases | 1 | idx_case_name | 1 | name | A | 6 | NULL | NULL | YES | BTREE | | |
| cases | 1 | idx_account_id | 1 | account_id | A | 6 | NULL | NULL | YES | BTREE | | |
| cases | 1 | idx_cases_stat_del | 1 | assigned_user_id | A | 3 | NULL | NULL | YES | BTREE | | |
| cases | 1 | idx_cases_stat_del | 2 | status | A | 6 | NULL | NULL | YES | BTREE | | |
| cases | 1 | idx_cases_stat_del | 3 | deleted | A | 6 | NULL | NULL | YES | BTREE | | |
| cases | 1 | idx_cases_tmst_id | 1 | team_set_id | A | 3 | NULL | NULL | YES | BTREE | | |
| cases | 1 | deleted | 1 | deleted | A | 3 | NULL | NULL | YES | BTREE | | |
| cases | 1 | team_id | 1 | team_id | A | 3 | NULL | NULL | YES | BTREE | | |
+-------+------------+--------------------+--------------+------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
mysql> show indexes from team_sets_teams;
+-----------------+------------+--------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-----------------+------------+--------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| team_sets_teams | 1 | idx_ud_set_id | 1 | team_set_id | A | 13 | NULL | NULL | YES | BTREE | | |
| team_sets_teams | 1 | idx_ud_set_id | 2 | team_id | A | 13 | NULL | NULL | YES | BTREE | | |
| team_sets_teams | 1 | idx_ud_team_id | 1 | team_id | A | 13 | NULL | NULL | YES | BTREE | | |
| team_sets_teams | 1 | deleted | 1 | deleted | A | 2 | NULL | NULL | YES | BTREE | | |
| team_sets_teams | 1 | idx_ud_team_set_id | 1 | team_set_id | A | 13 | NULL | NULL | YES | BTREE | | |
+-----------------+------------+--------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
【讨论】:
【参考方案3】:大部分时间都花在将临时表复制到磁盘上。当临时表中的数据太大而 MySQL 无法根据其配置设置保存在 RAM 中时,就会发生这种情况。
尝试增加您的tmp_table_size
和max_heap_table_size
MySQL 设置。这应该可以防止将临时表移动到磁盘,从而加快查询速度(如果您的服务器有足够的 RAM 来处理它;这将取决于您在 SugarCRM 中同时拥有多少用户)。
这里的瓶颈现在看起来是您的磁盘 i/o - 将服务器升级到我们的 SSD 也将具有性能优势,如果不是针对此查询(增加上述设置)而是针对整个 SugarCRM。如果您无法增加上述设置以将临时表保留在 RAM 中,那么获得 SSD 将是下一个最佳选择。
【讨论】:
以上是关于SugarCRM 慢查询(在 MySQL 上)的主要内容,如果未能解决你的问题,请参考以下文章