mysql性能问题

时间:2009-06-10 03:12:39

标签: mysql

我有一个名为联系人的表,我们使用了近120万条记录 MyIsam引擎每当我们查询这个表时,mysql都会挂起来,所以现在我们正在尝试使用Innodb引擎,这样如果它减速,但它不会挂起其他人

所以我们想要快速使用Myisam,我们在这个表上尝试了很多索引,但是它会停止并挂起系统

应该做些什么来使它更快,它不应该挂断系统

这是表格:

CREATE TABLE `contacts` (
  `id` varchar(36) NOT NULL,
  `deleted` tinyint(1) NOT NULL default '0',
  `date_entered` datetime NOT NULL default '0000-00-00 00:00:00',
  `date_modified` datetime NOT NULL default '0000-00-00 00:00:00',
  `modified_user_id` varchar(36) default NULL,
  `assigned_user_id` varchar(36) default NULL,
  `created_by` varchar(36) default NULL,
  `team_id` varchar(36) default NULL,
  `salutation` varchar(5) default NULL,
  `first_name` varchar(100) default '',
  `last_name` varchar(100) default '',
  `username` varchar(25) default '',
  `lead_source` varchar(100) default NULL,
  `title` varchar(50) default NULL,
  `department` varchar(100) default NULL,
  `reports_to_id` varchar(36) default NULL,
  `birthdate` date default NULL,
  `do_not_call` char(3) default '0',
  `phone_home` varchar(25) default NULL,
  `phone_mobile` varchar(25) default NULL,
  `phone_work` varchar(25) default '',
  `phone_other` varchar(25) default NULL,
  `phone_fax` varchar(25) default '',
  `email1` varchar(100) default '',
  `email2` varchar(100) default NULL,
  `assistant` varchar(75) default NULL,
  `assistant_phone` varchar(25) default NULL,
  `email_opt_out` char(3) default 'off',
  `primary_address_street` varchar(150) default NULL,
  `primary_address_city` varchar(100) default NULL,
  `primary_address_state` varchar(100) default NULL,
  `primary_address_postalcode` varchar(20) default NULL,
  `primary_address_country` varchar(100) default NULL,
  `alt_address_street` varchar(150) default NULL,
  `alt_address_city` varchar(100) default NULL,
  `alt_address_state` varchar(100) default NULL,
  `alt_address_postalcode` varchar(20) default NULL,
  `alt_address_country` varchar(100) default NULL,
  `description` text,
  `portal_name` varchar(255) default NULL,
  `portal_active` tinyint(1) NOT NULL default '0',
  `portal_app` varchar(255) default NULL,
  `salesforceid` varchar(36) default NULL,
  `phone_direct` varchar(25) default NULL,
  `invalid_email` tinyint(1) default '0',
  `parent_is_lead` char(3) default 'no',
  `advisory_board_member` varchar(25) default NULL,
  `direct_marketing` varchar(25) default NULL,
  `efx_id` varchar(36) default NULL,
  `fax_opt_out` char(3) default 'off',
  `ppc_keyword` varchar(50) default NULL,
  `status` varchar(25) default NULL,
  `web_form` varchar(50) default NULL,
  `efx_export_date` datetime default NULL,
  `bmtn` varchar(225) default '',
  `employee_location` varchar(50) default NULL,
  `pronunciation` varchar(250) default NULL,
  `duplicate_of` varchar(36) default NULL,
  `job_category` varchar(50) default NULL,
  `last_ska_upload_key` varchar(50) default NULL,
  `persid` varchar(36) default NULL,
  `last_web_upload_key` varchar(50) default NULL,
  `last_webinar_upload_key` varchar(50) default NULL,
  `primary_address_latitude` float default NULL,
  `primary_address_longitude` float default NULL,
  `first_name_soundex` varchar(30) default NULL,
  `last_name_soundex` varchar(30) default NULL,
  `primary_address_street_soundex` varchar(30) default NULL,
  `campaign_id` varchar(36) default NULL,
  `portal_password` varchar(32) default NULL,
  `pss_branch` varchar(40) default NULL,
  `pss_id` int(12) default NULL,
  `source_detail` varchar(100) default NULL,
  `source` varchar(100) default NULL,
  `pss_region` varchar(30) default NULL,
  `source_added` datetime default NULL,
  `terminated_user` char(3) default 'off',
  `invite_opt_out` char(3) default 'off',
  `newsletter_opt_out` char(3) default 'off',
  `stream_opt_out` char(3) default 'off',
  PRIMARY KEY  (`id`),
  KEY `idx_contacts_del_last` (`deleted`,`last_name`),
  KEY `idx_cont_del_reports` (`deleted`,`reports_to_id`,`last_name`),
  KEY `idx_contact_del_team` (`deleted`,`team_id`),
  KEY `idx_contact_salesforceid` (`salesforceid`),
  KEY `idx_contacts_username` (`username`),
  KEY `idx_email_opt_out` (`email_opt_out`),
  KEY `idx_primary_address_street` (`primary_address_street`),
  KEY `idx_primary_address_city` (`primary_address_city`),
  KEY `idx_primary_address_state` (`primary_address_state`),
  KEY `idx_primary_address_postalcode` (`primary_address_postalcode`),
  KEY `idx_primary_address_country` (`primary_address_country`),
  KEY `idx_modified_user_id` (`modified_user_id`),
  KEY `idx_assigned_user_id` (`assigned_user_id`),
  KEY `idx_created_by` (`created_by`),
  KEY `idx_team_id` (`team_id`),
  KEY `idx_reports_to_id` (`reports_to_id`),
  KEY `idx_contacts_efx_id` (`efx_id`),
  KEY `idx_contacts_title1` (`title`,`deleted`),
  KEY `idx_contacts_email1` (`email1`),
  KEY `idx_contacts_email2` (`email2`),
  KEY `idx_contacts_job_category` (`job_category`),
  KEY `idx_contacts_first_name_sdx` (`first_name_soundex`),
  KEY `idx_contacts_primary_street_sdx` (`primary_address_street_soundex`),
  KEY `idx_contacts_last_name_sdx` (`last_name_soundex`),
  KEY `idx_contacts_portal_name` (`portal_name`),
  KEY `idx_contacts_portal_active` (`portal_active`),
  KEY `idx_contacts_del_last_first` (`deleted`,`last_name`,`first_name`),
  KEY `idx_contacts_del_first` (`deleted`,`first_name`),
  KEY `idx_pss_id` (`pss_id`),
  KEY `idx_phone_work_last_name_first_name_deleted` (`phone_work`,`last_name`,`first_name`,`deleted`),
  KEY `idx_phone_work_last_name_first_name_deleted_sdx` (`phone_work`,`last_name_soundex`,`first_name_soundex`,`deleted`),
  KEY `idx_email1_last_name_first_name_deleted` (`email1`,`last_name`,`first_name`,`deleted`),
  KEY `idx_email1_last_name_first_name_deleted_sdx` (`email1`,`last_name_soundex`,`first_name_soundex`,`deleted`),
  KEY `idx_phone_fax_last_name_first_name_deleted` (`phone_fax`,`last_name`,`first_name`,`deleted`),
  KEY `idx_phone_fax_last_name_first_name_deleted_sdx` (`phone_fax`,`last_name_soundex`,`first_name_soundex`,`deleted`),
  KEY `idx_phone_work_last_name_deleted` (`phone_work`,`last_name`,`deleted`),
  KEY `idx_phone_work_last_name_deleted_sdx` (`phone_work`,`last_name_soundex`,`deleted`),
  KEY `idx_email1_last_name_deleted` (`email1`,`last_name`,`deleted`),
  KEY `idx_email1_last_name_deleted_sdx` (`email1`,`last_name_soundex`,`deleted`),
  KEY `idx_phone_fax_last_name_deleted` (`phone_fax`,`last_name`,`deleted`),
  KEY `idx_phone_fax_last_name_deleted_sdx` (`phone_fax`,`last_name_soundex`,`deleted`),
  KEY `idx_email1_first_name_deleted` (`email1`,`first_name`,`deleted`),
  KEY `idx_email1_first_name_deleted_sdx` (`email1`,`first_name_soundex`,`deleted`),
  KEY `idx_phone_fax_first_name_deleted` (`phone_fax`,`first_name`,`deleted`),
  KEY `idx_phone_fax_first_name_deleted_sdx` (`phone_fax`,`first_name_soundex`,`deleted`),
  KEY `idx_email1_deleted` (`email1`,`deleted`),
  KEY `idx_last_name_first_name_deleted_sdx` (`last_name_soundex`,`first_name_soundex`,`deleted`),
  KEY `idx_phone_mobile_deleted` (`phone_mobile`,`deleted`,`id`),
  KEY `idx_first_name_bmtn` (`first_name`,`bmtn`),
  KEY `idx_first_name_bmtn_email1` (`first_name`,`bmtn`,`email1`),
  KEY `idx_bmtn_email1` (`bmtn`,`email1`),
  KEY `idx_deleted` (`deleted`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

-

SELECT acc.id, acc.name, con_reports_to.first_name, con_reports_to.last_name
from contacts
left join accounts_contacts a_c on a_c.contact_id = '9802f40d-78bb-8dd4-dfaa-43f1064ccd5e' and a_c.deleted=0
left join accounts acc on a_c.account_id = acc.id and acc.deleted=0
left join contacts con_reports_to on con_reports_to.id = contacts.reports_to_id
where contacts.id = '9802f40d-78bb-8dd4-dfaa-43f1064ccd5e'

2 个答案:

答案 0 :(得分:1)

我怀疑断言“每当我们查询此表时mysql挂起”都是过分的 - 例如,对于MyISAM,SELECT COUNT(*) FROM TheTable应该非常快,基本上“无论什么”。当然,一些查询会很慢 - 尤其是如果表没有为查询正确编制索引,或者MySQL的所谓优化器选择了错误的策略(但你可以给它提示)。

为什么不向我们展示CREATE TABLE(包括索引),一些花费太长时间的查询,理想情况下精确衡量它们需要多长时间,这些情侣查询的EXPLAIN SELECT(& c)输出 - 我打赌我们真的可能会有所帮助!

编辑:CREATE TABLE基本上表明该表太过“广泛” - 太多列 - 期望体面的性能(即使没有显示任何查询)。该模式需要重新设计,将这个巨大的单片表(例如,地址相关信息)的块分解成其他辅助表。究竟如何最好地完成它取决于最优化的查询,因此,不知道有问题的查询,我甚至不会尝试任务。

再次编辑:所以查询已发布并使用其他表格accountsaccount_contacts,以及描述的广泛contacts表格;发布的查询(试图通过格式化& c来理解它)是:

SELECT acc.id, acc.name, con_reports_to.first_name, con_reports_to.last_name
FROM contacts 
LEFT JOIN accounts_contacts a_c 
          ON a_c.contact_id = '9802f40d-78bb-8dd4-dfaa-43f1064ccd5e' AND
             a_c.deleted=0 
LEFT JOIN accounts acc 
          ON a_c.account_id = acc.id AND 
             acc.deleted=0
LEFT JOIN contacts con_reports_to 
          ON con_reports_to.id = contacts.reports_to_id
WHERE contacts.id = '9802f40d-78bb-8dd4-dfaa-43f1064ccd5e'

为什么此处LEFT JOIN而不是普通INNER加入?在每种情况下,右侧工作台上是否都没有相应的行?例如,如果a_c中没有contact_iddeleted的给定值,则第一个a_cLEFT JOIN的所有字段都将为NULL,因此acc也不会有任何对应关系:在这种情况下,排名NULL, NULL作为前两列是否很重要?此外JOINa_c的{​​{1}}条件对acc完全没有任何引用,因此这将是一个笛卡尔积:从contacts中选择的每一行,如果有的话,将与从acc中选择的每一行配对。因此,con_reports_to / a_c查询可以完全与acccontacts上的查询分开,可能会大大加快查询(两个逻辑上分开的结果当然可以很容易再次聚集在客户端)。

对于这个复杂的查询,con_reports说了什么?对于我建议的两个较轻的单独的查询,它说了什么? EXPLAIN SELECTaccounts表中有哪些索引?

答案 1 :(得分:0)

横向分裂?虽然我想120万条记录并没有引入横向分裂......尝试找到底部的颈部...也问题可能在于您的硬件,例如硬盘几乎已满等等。