2009-06-10 11 views
0

J'ai une table nommée contacts qui a près de 1,2 million d'enregistrements que nous utilisons MyIsam moteur chaque fois que nous interrogeons cette table mysql pend vers le bas alors maintenant nous essayons nos mains avec le moteur Innodb de sorte que si elle ralentit, mais ne se bloque pas pour d'autresmysql numéro de performance

nous voulons donc faire rapidement avec MyISAM, nous avons essayé de nombreux indices sur cette table, mais il va vers le bas et bloque le système

Que faut-il faire pour le rendre plus rapide et il ne devrait pas se bloquer le système

Ceci est le tableau:

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' 
+0

écrire des requêtes efficaces et déterminer les bons index? –

+0

Pourriez-vous décrire votre configuration matérielle ... –

+0

Linux serveur de boîte avec 4 Go de RAM 60 Go partition pour DB mysql 5.1 et Apache 1,33 – maxjackie

Répondre

1

Je soupçonne l'assertion "chaque fois que nous interrogeons cette table mysql se bloque" est une overbid - par exemple, avec MyISAM, SELECT COUNT(*) FROM TheTable devrait être très rapide, essentiellement "peu importe quoi". Bien sûr, certains requêtes seront lents - en particulier si la table n'est pas indexée correctement pour les requêtes, ou si l'optimiseur présumé de MySQL choisit la mauvaise stratégie (mais vous pouvez lui donner des conseils).

Pourquoi ne nous montrez-vous pas les CREATE TABLE (y compris les indices), deux des requêtes qui prennent trop de temps, idéalement une mesure précise de combien de temps ils prennent, et la sortie de EXPLAIN SELECT (& c) ces questions de couple - je parie que nous pourrions vraiment être d'un peu d'aide alors! Edit: le CREATE TABLE montre essentiellement que la table est trop "large" - beaucoup trop de colonnes - pour obtenir des performances correctes (même si aucune requête n'a été affichée). Le schéma a besoin d'une nouvelle conception, en fragmentant les morceaux de cette énorme table monolithique (par exemple, les informations liées à l'adresse) en d'autres tables auxiliaires. Exactement comment le faire au mieux dépend entièrement des requêtes qui sont les plus importantes à optimiser, donc, ne sachant pas les requêtes en question, je ne vais même pas tenter la tâche. Editer à nouveau: donc la requête a été validée et utilise d'autres tables, accounts et account_contacts, ainsi que le très étendu contacts décrit; la requête telle que publiée (en essayant de comprendre en formatant & c) est:

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' 

Pourquoi les LEFT JOIN s ici au lieu de INNER join normal? Est-il possible dans chaque cas qu'il n'y ait pas de ligne correspondante sur la table de droite? Par exemple, s'il n'y a pas de ligne dans a_c avec les valeurs données pour contact_id et deleted, tous les champs de a_c dans la première LEFT JOIN seront NULL, afin qu'il n'y ait pas de correspondance pour acc soit: il est important d'émettre NULL, NULL comme deux premières colonnes dans ce cas?De plus, les conditions JOIN pour a_c et acc ne font aucune référence à contacts, donc ce sera un produit cartésien: chaque ligne sélectionnée parmi acc, le cas échéant, se jumellera avec chaque ligne sélectionnée parmi con_reports_to. Ainsi, la requête a_c/acc pourrait être entièrement séparée de celle sur contacts et con_reports, en alléguant vraisemblablement la requête considérablement (les deux résultats logiquement séparés pourraient bien sûr être facilement reconstitués dans le client). Qu'est-ce que EXPLAIN SELECT dit pour cette question complexe et que dit-il pour les deux distinctes distinctes que je suggère? Quels sont les indices sur les tables accounts et account_contact?

+0

Salut j'ai ajouté l'instruction de création de table – maxjackie

+0

a également ajouté la requête – maxjackie

0

division horizontale? bien que je suppose que 1,2 millions de disques ne sont pas beaucoup pour introduire le fractionnement horizontal .. essayer de localiser le cou inférieur ... aussi le problème peut se trouver avec votre matériel ainsi par exemple disque dur presque plein etc

+0

non je pense que la taille de la base de données de 15 Go et disque dur de 60 Go – maxjackie