Heim >Backend-Entwicklung >PHP-Tutorial >Eine bestimmte Tabellenverbindungsabfrage in der MySQL-Datenbank ist sehr langsam. Wie kann sie optimiert werden?

Eine bestimmte Tabellenverbindungsabfrage in der MySQL-Datenbank ist sehr langsam. Wie kann sie optimiert werden?

WBOY
WBOYOriginal
2016-08-04 09:21:181674Durchsuche

Die Verbindungsabfrage zwischen zwei Tabellen ist sehr langsam, aber wenn Sie nur eine Tabelle abfragen, ist sie sehr schnell, oder die Verbindungsabfrage anderer Tabellen ist auch sehr schnell.

Abfrageanweisung (Abfragezeit etwa eine halbe Sekunde):

<code>SELECT * FROM member m LEFT JOIN gift g ON g.mid = m.id WHERE m.status = 0 AND m.wid = 236 ORDER BY m.id DESC LIMIT 0,20</code>

Struktur der Mitgliedertabelle (ca. 40.000 Daten):

<code>CREATE TABLE `member` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `wid` int(11) NOT NULL,
  `wxid` varchar(30) DEFAULT NULL,
  `wid_wxid` varchar(30) DEFAULT NULL,
  `cpai` varchar(32) NOT NULL,
  `name` varchar(20) DEFAULT NULL,
  `sex` varchar(10) DEFAULT NULL,
  `tel` varchar(11) DEFAULT NULL,
  `lxtel` varchar(11) DEFAULT NULL,
  `xingge` varchar(10) DEFAULT NULL,
  `qq` int(11) DEFAULT NULL,
  `birthday` varchar(12) DEFAULT NULL,
  `cartype` varchar(20) DEFAULT NULL,
  `carclass` varchar(20) DEFAULT NULL,
  `bxtime` varchar(20) DEFAULT '0.00',
  `next_bxtime` varchar(20) DEFAULT '0.00',
  `bytime` varchar(20) DEFAULT '0.00',
  `next_bytime` varchar(20) DEFAULT '0.00',
  `bylong` varchar(20) DEFAULT '0.00',
  `next_bylong` varchar(20) DEFAULT '0.00',
  `engine` varchar(50) DEFAULT NULL,
  `chejia` varchar(50) DEFAULT NULL,
  `danganhao` varchar(30) DEFAULT NULL,
  `buy_date` varchar(20) DEFAULT NULL,
  `first_date` varchar(20) DEFAULT NULL,
  `weixiu_times` tinyint(4) DEFAULT NULL,
  `weixiu_money` decimal(8,2) DEFAULT NULL,
  `last_date` varchar(20) DEFAULT NULL,
  `last_jieche` varchar(50) DEFAULT NULL,
  `cpai_register` varchar(20) DEFAULT NULL,
  `identify_number` varchar(20) DEFAULT NULL,
  `order_number` varchar(20) DEFAULT NULL,
  `sale_date` varchar(20) DEFAULT NULL,
  `carkilometre` int(11) DEFAULT '0',
  `address` varchar(32) DEFAULT NULL,
  `remark` varchar(32) DEFAULT NULL,
  `is_check` int(11) DEFAULT '0',
  `password` char(6) DEFAULT NULL,
  `salt` char(32) DEFAULT NULL,
  `pay_password` char(32) DEFAULT NULL,
  `pay_salt` char(6) DEFAULT NULL,
  `status` tinyint(4) DEFAULT '0',
  `time` varchar(24) NOT NULL,
  `headimgurl` varchar(200) DEFAULT NULL,
  `nickname` varchar(32) DEFAULT NULL,
  `isattention` tinyint(4) DEFAULT '0',
  `paid_price` decimal(8,2) DEFAULT '0.00',
  `source` int(11) DEFAULT NULL,
  `add_date` datetime DEFAULT NULL,
  `add_by` varchar(30) DEFAULT '',
  `update_date` datetime DEFAULT NULL,
  `update_by` varchar(30) DEFAULT '',
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=59151 DEFAULT CHARSET=utf8;
</code>

Geschenktabellenstruktur (ca. 4000 Daten):

<code>CREATE TABLE `member_giftamount` (
  `id` int(16) NOT NULL AUTO_INCREMENT,
  `wid` int(32) NOT NULL,
  `mid` int(11) NOT NULL,
  `auth_wid` int(11) DEFAULT NULL,
  `wxid` varchar(64) DEFAULT NULL,
  `tel` varchar(30) DEFAULT NULL,
  `amount` decimal(8,2) DEFAULT '0.00',
  `gift_amount` decimal(8,2) DEFAULT '0.00',
  `refund_amount` decimal(8,2) DEFAULT '0.00',
  `credits` int(11) DEFAULT '0',
  `total` decimal(8,2) DEFAULT '0.00',
  `market_total` decimal(8,2) DEFAULT '0.00',
  `wid_wxid` varchar(64) DEFAULT NULL,
  `wait_total` decimal(8,2) DEFAULT '0.00',
  `add_date` datetime DEFAULT NULL,
  `add_by` varchar(30) DEFAULT NULL,
  `update_date` datetime DEFAULT NULL,
  `update_by` varchar(30) DEFAULT NULL,
  `sign_days` int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=4254 DEFAULT CHARSET=utf8;

</code>

Antwortinhalt:

Die Verbindungsabfrage zwischen zwei Tabellen ist sehr langsam, aber wenn Sie nur eine Tabelle abfragen, ist sie sehr schnell, oder die Verbindungsabfrage anderer Tabellen ist auch sehr schnell.

Abfrageanweisung (Abfragezeit etwa eine halbe Sekunde):

<code>SELECT * FROM member m LEFT JOIN gift g ON g.mid = m.id WHERE m.status = 0 AND m.wid = 236 ORDER BY m.id DESC LIMIT 0,20</code>

Struktur der Mitgliedertabelle (ca. 40.000 Daten):

<code>CREATE TABLE `member` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `wid` int(11) NOT NULL,
  `wxid` varchar(30) DEFAULT NULL,
  `wid_wxid` varchar(30) DEFAULT NULL,
  `cpai` varchar(32) NOT NULL,
  `name` varchar(20) DEFAULT NULL,
  `sex` varchar(10) DEFAULT NULL,
  `tel` varchar(11) DEFAULT NULL,
  `lxtel` varchar(11) DEFAULT NULL,
  `xingge` varchar(10) DEFAULT NULL,
  `qq` int(11) DEFAULT NULL,
  `birthday` varchar(12) DEFAULT NULL,
  `cartype` varchar(20) DEFAULT NULL,
  `carclass` varchar(20) DEFAULT NULL,
  `bxtime` varchar(20) DEFAULT '0.00',
  `next_bxtime` varchar(20) DEFAULT '0.00',
  `bytime` varchar(20) DEFAULT '0.00',
  `next_bytime` varchar(20) DEFAULT '0.00',
  `bylong` varchar(20) DEFAULT '0.00',
  `next_bylong` varchar(20) DEFAULT '0.00',
  `engine` varchar(50) DEFAULT NULL,
  `chejia` varchar(50) DEFAULT NULL,
  `danganhao` varchar(30) DEFAULT NULL,
  `buy_date` varchar(20) DEFAULT NULL,
  `first_date` varchar(20) DEFAULT NULL,
  `weixiu_times` tinyint(4) DEFAULT NULL,
  `weixiu_money` decimal(8,2) DEFAULT NULL,
  `last_date` varchar(20) DEFAULT NULL,
  `last_jieche` varchar(50) DEFAULT NULL,
  `cpai_register` varchar(20) DEFAULT NULL,
  `identify_number` varchar(20) DEFAULT NULL,
  `order_number` varchar(20) DEFAULT NULL,
  `sale_date` varchar(20) DEFAULT NULL,
  `carkilometre` int(11) DEFAULT '0',
  `address` varchar(32) DEFAULT NULL,
  `remark` varchar(32) DEFAULT NULL,
  `is_check` int(11) DEFAULT '0',
  `password` char(6) DEFAULT NULL,
  `salt` char(32) DEFAULT NULL,
  `pay_password` char(32) DEFAULT NULL,
  `pay_salt` char(6) DEFAULT NULL,
  `status` tinyint(4) DEFAULT '0',
  `time` varchar(24) NOT NULL,
  `headimgurl` varchar(200) DEFAULT NULL,
  `nickname` varchar(32) DEFAULT NULL,
  `isattention` tinyint(4) DEFAULT '0',
  `paid_price` decimal(8,2) DEFAULT '0.00',
  `source` int(11) DEFAULT NULL,
  `add_date` datetime DEFAULT NULL,
  `add_by` varchar(30) DEFAULT '',
  `update_date` datetime DEFAULT NULL,
  `update_by` varchar(30) DEFAULT '',
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=59151 DEFAULT CHARSET=utf8;
</code>

Geschenktabellenstruktur (ca. 4000 Daten):

<code>CREATE TABLE `member_giftamount` (
  `id` int(16) NOT NULL AUTO_INCREMENT,
  `wid` int(32) NOT NULL,
  `mid` int(11) NOT NULL,
  `auth_wid` int(11) DEFAULT NULL,
  `wxid` varchar(64) DEFAULT NULL,
  `tel` varchar(30) DEFAULT NULL,
  `amount` decimal(8,2) DEFAULT '0.00',
  `gift_amount` decimal(8,2) DEFAULT '0.00',
  `refund_amount` decimal(8,2) DEFAULT '0.00',
  `credits` int(11) DEFAULT '0',
  `total` decimal(8,2) DEFAULT '0.00',
  `market_total` decimal(8,2) DEFAULT '0.00',
  `wid_wxid` varchar(64) DEFAULT NULL,
  `wait_total` decimal(8,2) DEFAULT '0.00',
  `add_date` datetime DEFAULT NULL,
  `add_by` varchar(30) DEFAULT NULL,
  `update_date` datetime DEFAULT NULL,
  `update_by` varchar(30) DEFAULT NULL,
  `sign_days` int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=4254 DEFAULT CHARSET=utf8;

</code>

Indexoptimierung: Index zu g-Tabellenmitte hinzufügen; Index zu m-Tabellenstatus und -wid hinzufügen; langsame Abfrage, um zu sehen, ob der Index verwendet wird, versuchen, die Anzahl der Zeilen so klein wie möglich zu halten

  1. Index

    1. Index (id,wid,wxid,wid_wxid) in der Mitgliedertabelle

    2. Index (id,wid,mid,auth_wid,wxid) in der Geschenktabelle

    3. Wenn einige Felder häufig in Ihrer Where-Bedingung vorkommen, müssen Sie auch einen Index erstellen.

  2. Verwenden Sie nicht das *-Symbol : Listen Sie nur die erforderlichen Felder auf

  3. SQL-Referenz: Die SQL wurde direkt von mir geschrieben und nicht getestet

<code>select 不要用* from 
(SELECT m.status,m.wid,m.id FROM member m WHERE m.status = 0 AND m.wid = 236) a
LEFT JOIN gift g 
ON g.mid = a.id 
ORDER BY a.id DESC LIMIT 0,20</code>

Erstellen Sie einen Fremdschlüssel für das mittlere Feld von gift und verknüpfen Sie ihn mit der ID der Mitgliedstabelle

Ist es als Referenz wertvoll? Ich weiß nichts über Daten!
http://www.zhihu.com/question/37777220

Bitte veröffentlichen Sie den Ausführungsplan

Erstellen Sie einen Index mithilfe einer Unterabfrage.

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn