我有以下查询:
SELECT
COUNT(DISTINCT a0_.id) AS sclr0
FROM
account a0_
INNER JOIN customer c1_ ON (c1_.account = a0_.id)
LEFT JOIN sf_user_data s2_ ON (s2_.user_id = a0_.id)
LEFT JOIN address a3_ ON (c1_.customer_address = a3_.id)
WHERE
a3_.city IS NOT NULL
产生以下输出:
sclr0
+--------+
298279
使用以下EXPLAIN:
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
+--+---------------+-------+-----------+-------+--------------------------------------------+-----------------------+-----------+--------------------------------+-------+-----------+-------+
1 SIMPLE c1_ NULL ALL UNIQ_81398E097D3656A4,UNIQ_81398E091193CB3F NULL NULL NULL 405508 100.00 NULL
1 SIMPLE a0_ NULL eq_ref PRIMARY PRIMARY 8 evoportail.c1_.account 1 100.00 Using index
1 SIMPLE s2_ NULL eq_ref UNIQ_E904BFD1A76ED395 UNIQ_E904BFD1A76ED395 8 evoportail.c1_.account 1 100.00 Using index
1 SIMPLE a3_ NULL eq_ref PRIMARY PRIMARY 8 evoportail.c1_.customer_address 1 90.00 Using where
表格中的近似行数:
现在,此查询在3秒内运行。有没有办法加快速度?
CREATE语句:
CREATE TABLE `account` (
`id` bigint(20) unsigned NOT NULL auto_increment,
`identifier` varchar(255) collate utf8_bin NOT NULL,
`hash` varchar(255) collate utf8_bin default NULL,
`date_create` datetime default NULL,
`group` varchar(50) collate utf8_bin default NULL,
`sub_group` varchar(50) collate utf8_bin NOT NULL default 'NULL',
`date_last_action` datetime default NULL,
`date_last_connection` datetime default NULL,
`connection_counter` int(10) unsigned default NULL,
`connection_since_customer` int(10) unsigned NOT NULL default '0',
`salt` varchar(255) collate utf8_bin default NULL,
`roles` longtext collate utf8_bin COMMENT '(DC2Type:array)',
`is_v3` tinyint(1) NOT NULL default '1',
`password_token` varchar(255) collate utf8_bin default NULL,
`password_token_expired_at` datetime default NULL,
`is_included_in_newsletters` tinyint(1) NOT NULL default '0',
PRIMARY KEY (`id`),
UNIQUE KEY `identifier_UNIQUE` (`identifier`)
) ENGINE=MyISAM AUTO_INCREMENT=434243 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
CREATE TABLE `address` (
`id` bigint(20) unsigned NOT NULL auto_increment,
`city` varchar(64) collate utf8_bin default NULL,
`street` varchar(255) collate utf8_bin default NULL,
`complement` varchar(128) collate utf8_bin default NULL,
`zipcode` varchar(16) collate utf8_bin default NULL,
`country_id` int(11) default NULL,
`cedex` tinyint(1) NOT NULL default '0',
`abroad` tinyint(1) NOT NULL default '0',
PRIMARY KEY (`id`),
KEY `IDX_D4E6F81F92F3E70` (`country_id`)
) ENGINE=MyISAM AUTO_INCREMENT=541873 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
CREATE TABLE `customer` (
`id` bigint(20) unsigned NOT NULL auto_increment,
`account` bigint(20) unsigned NOT NULL,
`source` varchar(250) collate utf8_bin NOT NULL default 'DECLARATION',
`last_source` varchar(250) collate utf8_bin NOT NULL,
`source_domain_name` varchar(255) collate utf8_bin default NULL,
`subscription_offer` varchar(255) collate utf8_bin default NULL,
`formalities_center_address` bigint(20) unsigned default NULL,
`customer_address` bigint(20) unsigned default NULL,
`business_address` bigint(20) unsigned default NULL,
`shipping_address` bigint(20) default NULL,
`activity` text collate utf8_bin,
`state` enum('NONE','CREATE','UPDATE','COMPLETE') collate utf8_bin NOT NULL default 'NONE',
`num_dossier` varchar(255) collate utf8_bin default NULL,
`email` varchar(255) collate utf8_bin NOT NULL,
`lastname` varchar(255) collate utf8_bin NOT NULL,
`firstname` varchar(255) collate utf8_bin NOT NULL,
`sexe` int(1) NOT NULL default '0',
`activityset` int(1) NOT NULL default '0',
`phone` varchar(16) collate utf8_bin NOT NULL,
`business_name` varchar(255) collate utf8_bin default NULL,
`payment_method` enum('NONE','CB_OK','CB_KO','CHEQUE_OK','CHEQUE_KO','WAITING','IMPACTPLUS_OK','PRELEV') collate utf8_bin default 'NONE',
`payment_waiting_comment` text collate utf8_bin,
`sub_sent_recovery` smallint(6) default '0',
`transaction_number` varchar(30) collate utf8_bin default NULL,
`transaction_date` datetime default NULL,
`properties` set('ACCRE','CFE','WANT_WEBSITE','HAVE_WEBSITE','NEWSLETTER','SUBSCRIBE','OLD_CUSTOMER') collate utf8_bin default NULL,
`comments` text collate utf8_bin,
`activity_declaration` varchar(512) collate utf8_bin default NULL COMMENT 'file:///',
`cfe_center` varchar(255) collate utf8_bin default NULL,
`date_create` datetime default NULL,
`date_complete` datetime default NULL,
`date_subscribe` datetime default NULL,
`date_next_payement` datetime default NULL,
`date_ae_subscribe` datetime default NULL,
`siret` varchar(128) collate utf8_bin default NULL,
`current_quotation` bigint(20) unsigned default NULL,
`current_invoice` bigint(20) unsigned default NULL,
`has_create_quotation` tinyint(1) NOT NULL default '0',
`has_create_invoice` tinyint(1) NOT NULL default '0',
`created_by` int(20) NOT NULL default '0',
`updated_by` int(11) NOT NULL default '0',
`updated_date` datetime default NULL,
`abo_running` tinyint(1) NOT NULL default '1',
`show_bn` tinyint(1) NOT NULL default '1',
`taxe_type_activite` enum('NULL','ACHAT','SERVICE','BOTH') collate utf8_bin default NULL,
`taxe_categorie_activite` enum('NULL','COMMERCIALE','ARTISANALE','CIPAV','RSI') collate utf8_bin default NULL,
`taxe_liberatoire` enum('NULL','OUI','NON') collate utf8_bin default NULL,
`taxe_statut_accre` enum('NULL','OUI','NON','DK') collate utf8_bin default NULL,
`know` varchar(50) collate utf8_bin default NULL,
`sms_relance` int(11) default NULL,
`fdae` int(1) NOT NULL default '0',
`display_fdae` tinyint(1) NOT NULL default '0',
`show_dispense_immat` enum('RCS','RM','RSAC') collate utf8_bin default NULL,
`show_dispense_immat_city` varchar(255) collate utf8_bin default NULL,
`subscription_fdae` date default NULL,
`nbsocial` varchar(30) collate utf8_bin default NULL,
`atclic` int(1) NOT NULL default '0',
`merassurance` int(1) NOT NULL default '0',
`dossier_canceled` tinyint(1) NOT NULL default '0',
`dossier_canceled_date` datetime default NULL,
`tva_intra` varchar(20) collate utf8_bin default NULL,
`site_url` varchar(100) collate utf8_bin default NULL,
`freeguide` tinyint(1) NOT NULL default '0',
`hiscox` int(1) NOT NULL default '0',
`assurland` int(1) NOT NULL default '0',
`unpaid_advisor` int(11) default NULL,
`unpaid_date` datetime default NULL,
`ecl_send` tinyint(1) default NULL,
`ecl_date` datetime default NULL,
`birthdateyear` int(11) NOT NULL default '0',
`quaCategorie` varchar(500) collate utf8_bin default NULL,
`quaNature` varchar(500) collate utf8_bin default NULL,
`quaType` varchar(500) collate utf8_bin default NULL,
`april` int(1) NOT NULL default '0',
`date_guide` datetime default NULL,
`no_pub` tinyint(1) NOT NULL default '0',
`campaign_manual` tinyint(1) NOT NULL default '0',
`export_matmut` date default NULL,
`formality_date` datetime default NULL,
`call_count_commerciaux` int(11) default '0',
`call_count_assistance` int(11) default '0',
`call_last` datetime default NULL,
`prospect` tinyint(1) default NULL,
`gender_id` int(11) default NULL,
`birthdate` date default NULL,
`current_customer_source_history_id` int(11) default NULL,
`original_customer_source_history_id` int(11) default NULL,
`bounce` tinyint(1) NOT NULL default '0',
PRIMARY KEY (`id`),
UNIQUE KEY `UNIQ_81398E097D3656A4` (`account`),
UNIQUE KEY `UNIQ_81398E09E7927C74` (`email`),
UNIQUE KEY `UNIQ_81398E091193CB3F` (`customer_address`),
UNIQUE KEY `UNIQ_81398E09507DD4CC` (`business_address`),
UNIQUE KEY `UNIQ_81398E09BA38C653` (`formalities_center_address`),
KEY `num_dossier` (`num_dossier`),
KEY `sub_send_recovery` (`sub_sent_recovery`),
KEY `dossier_canceled` (`dossier_canceled`),
KEY `freeguide` (`freeguide`),
KEY `IDX_81398E09708A0E0` (`gender_id`),
KEY `IDX_81398E0935655550` (`current_customer_source_history_id`),
KEY `IDX_81398E0981A1F986` (`original_customer_source_history_id`)
) ENGINE=MyISAM AUTO_INCREMENT=433026 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
CREATE TABLE `sf_user_data` (
`id` int(11) NOT NULL auto_increment,
`user_id` bigint(20) unsigned NOT NULL,
`register_id` int(11) default NULL,
`insurance_id` int(11) default NULL,
`activity_started_at` date default NULL,
`accre_request_accepted` tinyint(1) default NULL,
`accre_request_accepted_at` date default NULL,
`declaration_frequency_months` smallint(6) default NULL,
`declaration_reminder` tinyint(1) default NULL,
`activities_number` smallint(6) default NULL,
`computed_main_activity_percent_total` double default NULL,
`computed_secondary_activity_percent_total` double default NULL,
`company_address_is_personal_address` tinyint(1) default NULL,
`register_city` varchar(255) collate utf8_unicode_ci default NULL,
`invoice_last_increment` smallint(6) NOT NULL default '0',
`quotation_last_increment` smallint(6) NOT NULL default '0',
`asset_last_increment` smallint(6) NOT NULL default '0',
`payplug_parameters` varchar(255) collate utf8_unicode_ci default NULL,
`displayed_first_connection_dialog` tinyint(1) NOT NULL default '0',
`displayed_first_invoice_display_dialog` tinyint(1) NOT NULL default '0',
`payplug_parameters_created_at` date default NULL,
`payplug_first_payment_at` date default NULL,
`latest_payplug_http_code` int(11) default NULL,
`register_number` varchar(255) collate utf8_unicode_ci default NULL,
`register_code` varchar(255) collate utf8_unicode_ci default NULL,
`register_bis_city` varchar(255) collate utf8_unicode_ci default NULL,
`register_bis_number` varchar(255) collate utf8_unicode_ci default NULL,
`registerBis_id` int(11) default NULL,
`main_activity_type_id` int(11) default NULL,
`secondary_activity_type_id` int(11) default NULL,
`declaration_reminder_popup` tinyint(1) default NULL,
`declaration_reminder_popup_latest_choice` smallint(6) default NULL COMMENT '1 = Me le rappeler demain, 2 = Ne plus afficher cette alerte',
`declaration_reminder_popup_latest_choice_date` date default NULL,
`main_activity_id` int(11) default NULL,
`secondary_activity_id` int(11) default NULL,
`primary_socio_economic_classification_id` int(11) default NULL,
`secondary_socio_economic_classification_id` int(11) default NULL,
`income_bracket_id` int(11) default NULL,
`main_activity_custom` varchar(255) collate utf8_unicode_ci default NULL,
`secondary_activity_custom` varchar(255) collate utf8_unicode_ci default NULL,
`default_further_information` longtext collate utf8_unicode_ci,
`gclid` varchar(255) collate utf8_unicode_ci default NULL,
`main_activity_type_old_id` smallint(6) default NULL,
`main_activity_nature_old_id` smallint(6) default NULL,
`secondary_activity_type_old_id` smallint(6) default NULL,
`secondary_activity_nature_old_id` smallint(6) default NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `UNIQ_E904BFD1A76ED395` (`user_id`),
UNIQUE KEY `UNIQ_E904BFD1D1E63CD1` (`insurance_id`),
KEY `IDX_E904BFD14976CB7E` (`register_id`),
KEY `IDX_E904BFD1DBC024CC` (`registerBis_id`),
KEY `IDX_E904BFD12E864BE8` (`main_activity_type_id`),
KEY `IDX_E904BFD132198C62` (`secondary_activity_type_id`),
KEY `IDX_E904BFD15543A800` (`main_activity_id`),
KEY `IDX_E904BFD1798B8812` (`secondary_activity_id`),
KEY `IDX_E904BFD1D17B29D3` (`primary_socio_economic_classification_id`),
KEY `IDX_E904BFD17758CEBC` (`secondary_socio_economic_classification_id`),
KEY `IDX_E904BFD1BAF920D3` (`income_bracket_id`)
) ENGINE=MyISAM AUTO_INCREMENT=116384 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
答案 0 :(得分:0)
似乎这个简单的修正案会更快:
SELECT COUNT(DISTINCT a0_.id) sclr0
FROM account a0_
JOIN customer c1_
ON c1_.account = a0_.id
JOIN address a3_
ON c1_.customer_address = a3_.id
如果数据完整性对您很重要,请考虑切换到InnoDB。
答案 1 :(得分:0)
将LEFT JOIN address a3
更改为普通JOIN
。这样,优化器可以考虑从address
开始。并将INDEX(city)
添加到address
。
目前,EXPLAIN
显示在3个表中的每个表中都有405K行。 (总共1.2M)通过上面的更改,优化器将从城市索引开始,通过查看,比方说1K行。之后,它将在其他两个表中的每一个中查找1K行。 (总共3K)
LEFT JOIN sf_user_data s2_ ON (s2_.user_id = a0_.id)
似乎完全没用;去掉它。 (现在低至2K行)
(255)
,请使用合理的数字。这样做,如果identifier
不是很大,请将其设为PRIMARY KEY
并删除id
。
极少有6个不同的列,每个列都是UNIQUE
。我认为你会因此遇到业务逻辑问题。