Heim >Datenbank >MySQL-Tutorial >Detaillierte Einführung in die Unterabfrage zur MySQL-Leistungsoptimierung
Ich erinnere mich, als ich an einem Projekt arbeitete, hörte ich ein Sprichwort: Versuchen Sie, keine Unterabfragen zu verwenden. Schauen wir uns also diesen Artikel an, um zu sehen, ob dieser Satz richtig ist.
Davor war es Es ist notwendig, einige konzeptionelle Dinge und die allgemeine Verarbeitung von Anweisungen durch MySQL einzuführen.
Wenn der Verbindungsthread von MySQL Server die vom Client gesendete SQL-Anfrage empfängt, durchläuft er eine Reihe von Zerlegungsanalysen und führt entsprechende Schritte durch Analyse, und dann verwendet MySQL das Abfrageoptimierungsmodul, um Berechnungen und Analysen basierend auf den relevanten statistischen Informationen der in SQL enthaltenen Datentabellen durchzuführen. Anschließend wird eine Datenzugriffsmethode abgeleitet, die MySQL als solche betrachtet Der vernünftigste und optimalste Weg ist, dass wir oft „Ausführungsplan“ sagen und dann die entsprechenden Daten abrufen, indem wir die Speicher-Engine-Schnittstelle gemäß dem erhaltenen Ausführungsplan aufrufen. Führen Sie dann die entsprechende Verarbeitung der zurückgegebenen Daten durch von der Speicher-Engine verarbeitet und gemäß den Anforderungen des Clients verarbeitet. Das Format wird als Ergebnismenge verwendet und an den Client zurückgegeben.
Hinweis: Bei den hier genannten statistischen Daten handelt es sich um einige Datenstatistiken, die wir erhalten, nachdem wir MySQL benachrichtigt haben um die relevanten Daten der Tabelle über den Befehl „Tabelle analysieren“ zu analysieren. Diese Daten sind für den MySQL-Optimierer sehr wichtig. Die Qualität des vom Optimierer generierten Ausführungsplans wird hauptsächlich durch diese statistischen Daten bestimmt.
1 . Tabelle erstellen
create table User( Id int not null PRIMARY key auto_increment , NickName varchar(50) comment '用户昵称', Sex int comment '性别', Sign varchar(50) comment '用户签名', Birthday datetime comment '用户生日', CreateTime datetime comment '创建时间') default charset=utf8 comment '用户表';create table UserGroup( Id int not null PRIMARY key auto_increment , UserId int not null comment 'user Id', GroupId int not null comment '用户组Id', CreateTime datetime comment '创建时间', -- key index_groupid(GroupId) using btree, key index_userid(groupid, UserId) using btree ) default charset=utf8 comment '用户组表';
2. Daten vorbereiten
var conStr = ConfigurationManager.ConnectionStrings["ConStr"].ToString(); using (IDbConnection conn = new MySqlConnection(conStr)) { Stopwatch watch = new Stopwatch(); var sql = string.Empty; var names = new string[] { "非", "想", "红", "帝", "德", "看", "梅", "插", "兔" }; Random ran = new Random(); var insertSql = @" insert into User(NickName,Sex,Sign, Birthday, CreateTime) values(@NickName,@Sex,@Sign, @Birthday, @CreateTime); INSERT INTO usergroup (UserId, GroupId, CreateTime ) VALUES (LAST_INSERT_ID() , @GroupId, @CreateTime);"; watch.Start(); if (conn.State == ConnectionState.Closed) { conn.Open(); } var tran = conn.BeginTransaction(); for (int i = 0; i < 100000; i++) { var param = new { NickName = names[ran.Next(9)] + names[ran.Next(9)] + i, Sign = names[ran.Next(9)] + names[ran.Next(9)], CreateTime = DateTime.Now, Birthday = DateTime.Now.AddYears(ran.Next(10, 30)), Sex = i % 2, GroupId = ran.Next(1, 100) }; conn.Execute(insertSql, param, tran); } tran.Commit(); conn.Dispose(); watch.Stop(); Console.WriteLine(watch.ElapsedMilliseconds); }
Hier habe ich 5000 Daten eingefügt und die Gruppe wurde zufällig in 99 Gruppen aufgeteilt 3. SQL abfragen
Sowohl der zweite als auch der dritte Satz verwenden Unterabfragen. Der Unterschied besteht darin, dass der zweite Satz zuerst 20 Daten abruft und diese dann der Benutzertabelle zuordnetexplain select user.id, user.nickname from usergroup left join user on usergroup.UserId = user.Id where usergroup.groupid = 1 order by usergroup.UserId desc limit 100, 20; explain select user.id, user.nickname from (select id, userid from usergroup where groupid = 1 order by userid limit 100, 20) t left join user on t.UserId = user.id ; explain select user.id, user.nickname from (select id, userid from usergroup where groupid = 1 order by userid ) t left join user on t.UserId = user.id limit 100, 20;
4 . Bei der Analyse von
100.000 Daten:
Lesen Sie zuerst den ersten Satz
und schauen Sie sich dann den zweiten Satz an
Der dritte Satz
Wenn wir uns die drei Bilder oben ansehen, scheinen wir es erkennen zu können Etwas.
Schauen Sie sich zuerst ihre Zeilen an, die sich auf mehr als 1.000 summieren. Die anderen beiden Sätze ergeben zusammen 996. Aber was ich sagen möchte, ist, hier nicht zu schauen bei der Summe der Zeilen. Die Methode besteht darin, mit der Anweisung mit der größeren ID zu beginnen und dann die Anweisungen mit derselben ID von oben nach unten auszuführen.
Schauen Sie sich dann die Anweisung mit der ID=2 an Der zweite Satz und die Anweisung mit der ID=1 im ersten Satz sind genau gleich. Sie filtern alle Daten aus der Benutzergruppentabelle und können die gleiche Ergebnismenge A erhalten.
Es scheint, dass sie es sind Als nächstes wird es Unterschiede geben.
Sehen Sie sich zuerst den ersten Satz an und gehen Sie dann basierend auf der Ergebnismenge A zum linken Join-Tabellenbenutzer und filtern Sie den endgültigen heraus Daten und geben Sie sie an den Client zurück.
Was ist mit dem zweiten Satz? Basierend auf A werden die Daten erneut gefiltert, um die erforderlichen Daten zu erhalten, und dann werden die Daten mit der Benutzertabelle verbunden, um sie zu erhalten das Endergebnis.
Aus der oben genannten Sicht ist der zweite Ausführungsplan effizienter
Wenn Sie den Umfang der Abfrage durch eine Unterabfrage erheblich reduzieren können , können Sie die Verwendung einer Unterabfrageanweisung in Betracht ziehen
Das obige ist der detaillierte Inhalt vonDetaillierte Einführung in die Unterabfrage zur MySQL-Leistungsoptimierung. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!