2016-12-09 3 views
0

Ich habe die folgende Abfrage:mehrere verbindet SQL-Abfrage-Optimierung

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 

in der folgenden Ausgabe führt:

sclr0 
+--------+ 
298279 

mit den folgenden ERKLÄREN:

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 

approximative Anzahl der Zeilen in den Tabellen:

  • Konto: 430000
  • Kunde: 430000
  • sf_user_data: 115000
  • Adresse: 550000

Gerade jetzt, diese Abfrage in 3 Sekunden läuft. Gibt es eine Möglichkeit, es zu beschleunigen?

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

Zusätzlich zu dem EXPLAIN erfordern Fragen dieser Art IMMER CREATE TABLE-Anweisungen für ALLE relevanten Tabellen. Es ist auch ungewöhnlich für OUTER JOIN-Tabellen, aus denen Sie keine Spalten auswählen. – Strawberry

+0

Warum denkst du 3 Sekunden ist langsam ??? – Rahul

+0

@Strawberry bearbeitet die Frage mit den Create-Anweisungen – VaN

Antwort

0

Es ist wie diese einfache Änderung scheint schneller sein:

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 

Und wenn die Datenintegrität für Sie wichtig ist, sollten Sie zu InnoDB umgeschaltet wird.

+1

Das ist nicht gleichwertig. Er kann (sollte) den "linken Join" von "s2_" ganz loswerden, aber nicht durch einen 'Join' ersetzen. Auch "city" kann "null" sein, also muss die 'where' Bedingung beibehalten werden. – Solarflare

+0

@Solarflare korrekt – Strawberry

+0

Wow, das war schnell. Ich bin mir nicht sicher, ob du meine Bearbeitung zu meinem Kommentar gesehen hast. Sie müssen auch die 'where' Bedingung beibehalten (alle Städte könnten" null "sein, wenn sie es wollten und jetzt zählen würden, aber nicht sollten). – Solarflare

0

Ändern Sie LEFT JOIN address a3 in Plain JOIN. Auf diese Weise könnte der Optimierer erwägen, mit address zu beginnen. Und füge INDEX(city) zu address hinzu.

Derzeit zeigt die EXPLAIN 405.000 Zeilen in jeder der 3 Tabellen. (1.2M total) Mit der obigen Änderung würde der Optimierer mit dem Stadtindex beginnen, indem er, sagen wir, 1K Reihen betrachtet. Danach würde es 1K Zeilen in jeder der anderen zwei Tabellen nachschlagen. (3K insgesamt)

LEFT JOIN sf_user_data s2_ ON (s2_.user_id = a0_.id) scheint völlig nutzlos zu sein; entfernen Sie es. (Jetzt bis 2K Zeilen)

Verwenden Sie nicht blind (255), verwenden Sie angemessene Zahlen. Wenn identifier nicht sehr groß ist, dann machen Sie es PRIMARY KEY und entfernen Sie id.

Es ist äußerst selten, dass 6 verschiedene Spalten jeweils UNIQUE sind. Ich denke, dass Sie dadurch in Geschäftslogikprobleme geraten werden.