Heim >Datenbank >MySQL-Tutorial >Detaillierte Interpretation von MySQL-Indizes und -Transaktionen
Dieser Artikel bietet Ihnen eine detaillierte Interpretation von MySQL-Indizes und -Transaktionen. Ich hoffe, dass er für Freunde hilfreich ist.
1. Was macht ein Index?
Wenn Ihre Anwendung SQL-Abfragen sehr langsam ausführt, sollten Sie darüber nachdenken, ob sie einen Index erstellen kann .
Die meisten MySQL-Indizes (PRIMARY KEY, UNIQUE, INDEX und FULLTEXT) werden in B-Bäumen gespeichert. Nur räumliche Spaltentypindizes verwenden R-Tree, und MEMORY-Tabellen unterstützen auch Hash-Indizes.
Der Index ist eine sortierte Liste, in der der Indexwert und die physische Adresse der Zeile mit den Daten gespeichert werden. Wenn die Daten sehr groß sind, kann der Index die Abfrage erheblich beschleunigen Mithilfe des Index müssen Sie nicht die gesamte Tabelle durchsuchen, um die Daten einer bestimmten Zeile zu finden. Stattdessen finden Sie zunächst die physische Adresse, die der Datenzeile entspricht, über die Indextabelle und greifen dann auf die entsprechenden Daten zu.
2. Vor- und Nachteile des Index
Vorteile: Schnelles Abrufen, kürzere E/A-Zeiten, schnelleres Gruppieren und Indizieren basierend auf Die Indexsortierung kann das Gruppieren und Sortieren beschleunigen.
Nachteile: Der Index selbst ist auch eine Tabelle, sodass der von der Indextabelle belegte Speicherplatz im Allgemeinen 1,5 beträgt Die Wartung und Erstellung von Indextabellen erfordert einen Zeitaufwand, der mit zunehmender Datenmenge zunimmt und die Effizienz von Änderungsvorgängen (Löschen, Hinzufügen, Ändern) der Datentabelle verringert Datentabelle sind gleichzeitig erforderlich.
3. Klassifizierung von Indizes
Gemeinsame Indextypen sind: Primärschlüsselindex, eindeutiger Index, gewöhnlicher Index, Volltextindex, kombinierter Index
1. Primärschlüsselindex : Das heißt, der Primärindex wird basierend auf dem Primärschlüssel pk_clolum (Länge) erstellt ). Duplikate sind nicht zulässig und Nullwerte sind nicht zulässig. Eindeutiger Index
: Der Wert der zum Erstellen des Index verwendeten Spalte muss eindeutig sein und darf keine Nullwerte enthalten sind erlaubtALTER TABLE 'table_name' ADD PRIMARY KEY('id');3. Gewöhnlicher Index: Erstellt mit gewöhnlichen Spalten im Tabellenindex, ohne Einschränkungen
ALTER TABLE 'table_name' ADD UNIQUE('email');4, Volltextindex : Index, der mit Spalten großer Textobjekte erstellt wird (wird im nächsten Teil erklärt)
ALTER TABLE 'table_name' ADD INDEX index_name('description');5, Kombinierter Index: Ein Index, der durch Kombination mehrerer Spalten erstellt wird. Die Werte In diesen Spalten sind keine Nullwerte zulässig
ALTER TABLE 'table_name' ADD FULLTEXT('content');Befolgen Sie das Prinzip des „ganz links stehenden Präfixes“ und verwenden Sie die am häufigsten verwendeten zum Abrufen oder Sortieren. Die Spalten werden ganz links in absteigender Reihenfolge platziert. Der kombinierte Index entspricht der Einrichtung von drei Indizes: col1, col1col2, col1col2col3, und Indizes können nicht für col2 oder col3 verwendet werden. Bei Verwendung eines kombinierten Index ist der Indexschlüssel möglicherweise zu groß, da der Spaltenname zu lang ist, was zu einer verringerten Effizienz führt. Wenn dies zulässig ist, können Sie nur die ersten paar Zeichen von Spalte 1 und Spalte 2 als verwenden Index.
ALTER TABLE 'table_name' ADD INDEX index_name('col1','col2','col3');bedeutet die Verwendung der ersten 4 Zeichen von Spalte 1 und der ersten 3 Zeichen von Spalte 2 als Index
4. Implementierungsprinzip des Index
MySQL-Unterstützung Es gibt viele Speicher-Engines und verschiedene Speicher-Engines bieten unterschiedliche Unterstützung für Indizes. Daher unterstützt die MySQL-Datenbank mehrere Indextypen, z. B. BTree-Index, B+Tree-Index, Hash-Index, Volltextindex usw.
1. Hash-Index: Nur die Speicher-Engine unterstützt den Hash-Index. Der Hash-Index verwendet den Wert der Indexspalte, um den Hash-Code des Werts zu berechnen, und speichert den Wert dann am entsprechenden Ort Auf den physischen Speicherort der Zeilendaten kann sehr schnell zugegriffen werden, da ein Hash-Algorithmus verwendet wird. Da es sich jedoch um eine Hash-Verteilungsmethode handelt, unterstützt der Hash-Index keinen Bereich Such- und Sortierfunktionen. 2. Volltextindex: VOLLTEXT-Index (Volltext), der nur für MyISAM und InnoDB verwendet werden kann, ist die Erstellung eines Volltextindex sehr zeitaufwändig -aufwändig und platzraubend. Wenn Sie bei großen Textobjekten oder größeren Daten vom Typ CHAR einen normalen Index verwenden, ist es immer noch möglich, die ersten Zeichen des Textes abzugleichen. Wenn Sie jedoch einige Wörter in der Mitte des Textes abgleichen möchten, müssen Sie diesen verwenden LIKE %word% Die Verarbeitung dauert lange und die Antwortzeit wird erheblich verlängert. In diesem Fall können Sie den FULLTEXT-Index verwenden, um eine Liste mit Wörtern zu erstellen Der Text wird zeitlich indexiert, basierend auf dieser Wortliste. VOLLTEXT kann beim Erstellen der Tabelle erstellt oder bei Bedarf mit ALTER oder CREATE INDEX hinzugefügt werden:ALTER TABLE 'table_name' ADD INDEX index_name(col1(4),col2(3));
Die Höhe jedes Blattknotens ist gleich h;
Jeder Nicht-Blattknoten besteht aus n-1 Schlüsseln und n Zeigern, wobei d
Blattknotenzeiger sind null; key stellt den Schlüssel als Index dar, und data sind die Daten der Zeile, in der sich der Schlüsselwert befindet. Die Struktur von
BTree ist wie folgt:
In der Struktur von BTree können Sie die binäre Suchmethode verwenden. Die Suchkomplexität ist im Allgemeinen sehr klein, normalerweise etwa 3. Daher ist BTree eine sehr effiziente Suchstruktur.
B+Tree-Index
Die Nicht-Blattknoten in B+Tree speichern keine Daten, sondern nur Schlüsselwerte;
Die Blattknoten von B+Tree haben keine Zeiger und alle Schlüsselwerte wird auf den Blattknoten angezeigt und die physische Adresse der Daten, die dem im Schlüssel gespeicherten Schlüsselwert entsprechen
Die Struktur von B+Tree ist wie folgt:
Im Allgemeinen ist B + Tree besser geeignet als BTree, um die Indexstruktur des externen Speichers zu implementieren, da die Experten für Speicher-Engine-Design die Speicherstruktur des externen Speichers (Festplatte) geschickt nutzen. Das heißt, ein Sektor der Festplatte ist ein ganzzahliges Vielfaches einer Seite (Seite), und Seite ist die Speichereinheit in A. Der Standardwert ist normalerweise 4 KB, sodass die Knoten der Indexstruktur so ausgelegt sind, dass sie die Größe einer Seite haben Verwenden Sie dann das „Vorlese“-Prinzip des externen Speichers, um die Daten des gesamten Knotens jedes Mal zu lesen, wenn sie im Speicher gelesen werden. Es ist bekannt, dass die Lesegeschwindigkeit des Speichers Hunderte beträgt Das heißt, der Schlüssel zur Verbesserung der Suchgeschwindigkeit liegt darin, so wenig Festplatten-E/A wie möglich zu verwenden. Dann können Sie wissen: Je mehr Schlüssel in jedem Knoten vorhanden sind, desto kleiner ist die Höhe des Knotens Daher ist B+Tree im Allgemeinen schneller als BTree, da es in B+Tree keine Nicht-Blattknoten gibt und Sie mehr Schlüssel speichern können.
B+TREE mit sequentiellem Index
Die Struktur von B+Tree ist wie folgt:
Das Implementierungsprinzip der Indexstruktur von MySQL wird analysiert, und dann werden wir Schauen Sie sich die Details an. Wie implementieren Speicher-Engines Indexstrukturen? Die beiden häufigsten Speicher-Engines in MySQL sind MyISAM und InnoDB, die nicht gruppierte Indizes bzw. gruppierte Indizes implementieren.
Zunächst müssen wir einige Konzepte bei der Klassifizierung von Indizes einführen. Wir können sie in „Primärindex“ und „Hilfsindex“ unterteilen, je nachdem, ob der Schlüssel des Index der Primärschlüssel ist Der anhand des Primärschlüsselwerts erstellte Index wird „Primärindex“ genannt, die anderen werden „Hilfsindizes“ genannt. Daher kann es nur einen Primärindex und viele Hilfsindizes geben.
MyISAM – nicht gruppierter Index
Die Datentabelle und die Indextabelle des nicht gruppierten Index werden separat gespeichert.
Die Daten im nicht gruppierten Index werden entsprechend der Einfügereihenfolge der Daten gespeichert. Daher eignen sich nicht gruppierte Indizes besser für Abfragen einzelner Daten. Die Einfügungsreihenfolge wird nicht durch Schlüsselwerte beeinflusst.
VOLLTEXT-Indizes sind nur in MyISAM verfügbar.
Zuerst habe ich nie verstanden, warum der Hilfsindex benötigt wird, da der Primärindex und der Hilfsindex des nicht gruppierten Index auf denselben Inhalt verweisen. Später wurde mir klar, dass der Index nicht für die Verwendung in verwendet wird Ist das nicht direkt nach den Anweisungen WHERE und ORDER BY der Fall, wenn die Abfragebedingung zu diesem Zeitpunkt nicht der Primärschlüssel ist?
InnoDB - Clustered Index
Die Daten des Clustered-Index und des Primärschlüsselindex werden zusammen gespeichert.
Die Daten im Clustered-Index werden in der Reihenfolge des Primärschlüssels gespeichert. Daher eignet es sich für die Intervallsuche nach Primärschlüsselindex, was weniger Festplatten-E/A erfordern und die Abfrage beschleunigen kann. Aber auch aus diesem Grund ist es am besten, die Einfügereihenfolge des Clustered-Index in der monotonen Reihenfolge des Primärschlüssels einzufügen, da es sonst häufig zu Seitenteilungen kommt, die die Leistung erheblich beeinträchtigen.
Wenn Sie in InnoDB nur nach indizierten Spalten suchen müssen, versuchen Sie, keine weiteren Spalten hinzuzufügen, um die Abfrageeffizienz zu verbessern.
使用主索引的时候,更适合使用聚簇索引,因为聚簇索引只需要查找一次,而非聚簇索引在查到数据的地址后,还要进行一次I/O查找数据。
因为聚簇辅助索引存储的是主键的键值,因此可以在数据行移动或者页分裂的时候降低委会成本,因为这时不用维护辅助索引。但是辅助索引会占用更多的空间。
聚簇索引在插入新数据的时候比非聚簇索引慢很多,因为插入新数据时需要减压主键是否重复,这需要遍历主索引的所有叶节点,而非聚簇索引的叶节点保存的是数据地址,占用空间少,因此分布集中,查询的时候I/O更少,但聚簇索引的主索引中存储的是数据本身,数据占用空间大,分布范围更大,可能占用好多的扇区,因此需要更多次I/O才能遍历完毕。
下图可以形象的说明聚簇索引和非聚簇索引的区别
什么时候要使用索引?
主键自动建立唯一索引;
经常作为查询条件在WHERE或者ORDER BY 语句中出现的列要建立索引;
作为排序的列要建立索引;
查询中与其他表关联的字段,外键关系建立索引
高并发条件下倾向组合索引;
什么时候不要使用索引?
经常增删改的列不要建立索引;
有大量重复的列不建立索引;
表记录太少不要建立索引;
在组合索引中不能有列的值为NULL,如果有,那么这一列对组合索引就是无效的;
在一个SELECT语句中,索引只能使用一次,如果在WHERE中使用了,那么在ORDER BY中就不要用了;
LIKE操作中,'%aaa%'不会使用索引,也就是索引会失效,但是‘aaa%’可以使用索引;
在索引的列上使用表达式或者函数会使索引失效,例如:select from users where YEAR(adddate) from users where adddate 在查询条件中使用正则表达式时,只有在搜索模板的第一个字符不是通配符的情况下才能使用索引。 在查询条件中使用会导致索引失效。 在查询条件中使用IS NULL会导致索引失效。 在查询条件中使用OR连接多个条件会导致索引失效,这时应该改为两次查询,然后用UNION ALL连接起来。 尽量不要包括多列排序,如果一定要,最好为这队列构建组合索引; 只有当数据库里已经有了足够多的测试数据时,它的性能测试结果才有实际参考价值。如果在测试数据库里只有几百条数据记录,它们往往在执行完第一条查询命令之后就被全部加载到内存里,这将使后续的查询命令都执行得非常快--不管有没有使用索引。只有当数据库里的记录超过了1000条、数据总量也超过了MySQL服务器上的内存总量时,数据库的性能测试结果才有意义。 六、索引的优化 索引的最左前缀和和B+Tree中的“最左前缀原理”有关,举例来说就是如果设置了组合索引 根据最左前缀原则,我们一般把排序分组频率最高的列放在最左边,以此类推。 在上面已经提到,使用LIKE进行模糊查询的时候,'%aaa%'不会使用索引,也就是索引会失效。如果是这种情况,只能使用全文索引来进行优化(上文有讲到)。 为检索的条件构建全文索引,然后使用 首先,什么是事务?事务就是一段sql 语句的批处理,但是这个批处理是一个atom(原子),不可分割,要么都执行,要么回滚(rollback)都不执行。 MySQL 事务主要用于处理操作量大,复杂度高的数据。比如说,在人员管理系统中,你删除一个人员,你即需要删除人员的基本资料,也要删除和该人员相关的信息,如信箱,文章等等,这样,这些数据库操作语句就构成一个事务! 在 MySQL 中只有使用了 Innodb 数据库引擎的数据库或表才支持事务。 Transaktionsverarbeitung kann verwendet werden, um die Integrität der Datenbank aufrechtzuerhalten und sicherzustellen, dass Stapel von SQL-Anweisungen entweder alle oder gar nicht ausgeführt werden. Transaktionen werden zum Verwalten von Einfügungs-, Aktualisierungs- und Löschanweisungen verwendet Im Allgemeinen müssen Transaktionen 4 Bedingungen (ACID) erfüllen: Atomizität (Atomizität ), Konsistenz (Stabilität), Isolation (Isolation), Haltbarkeit (Zuverlässigkeit) 1. Atomarität von Transaktionen: eine Reihe von Transaktionen, entweder erfolgreich oder zurückgezogen. 2. Stabilität: Bei illegalen Daten (Fremdschlüsselbeschränkungen und dergleichen) wird die Transaktion zurückgezogen. 3. Isolation: Transaktionen laufen unabhängig ab. Wenn sich das Ergebnis einer Transaktion auf andere Transaktionen auswirkt, werden die anderen Transaktionen zurückgezogen. Eine 100-prozentige Isolierung von Transaktionen erfordert Einbußen bei der Geschwindigkeit. 4. Zuverlässigkeit: Nach einem Software- oder Hardware-Absturz verwendet der InnoDB-Datentabellentreiber die Protokolldatei, um sie zu rekonstruieren und zu ändern. Zuverlässigkeit und hohe Geschwindigkeit sind nicht kompatibel. Die Option innodb_flush_log_at_trx_commit bestimmt, wann Transaktionen im Protokoll gespeichert werden.
Transaktionsparallelität führt keine Dirty Reads, Phantom Reads und nicht wiederholbaren Lesevorgänge durch, die durch Transaktionsisolation verursacht werden Dirty Read: Transaktion A liest die Daten, die durch die nicht festgeschriebene Transaktion B geändert wurden. Wenn Transaktion B auf halbem Weg kein Rollback durchführen kann, liest Transaktion A zu diesem Zeitpunkt Dirty Data. Transaktion A ändert beispielsweise Geld. Zu diesem Zeitpunkt liest Transaktion B die Aktualisierungsergebnisse von Transaktion A. Wenn Transaktion A jedoch später zurückgesetzt wird, handelt es sich bei den von Transaktion B gelesenen fehlerhaften Daten. Nicht wiederholbares Lesen: In derselben Transaktion sind die Ergebnisse des Lesens derselben Daten inkonsistent. Transaktion A liest, bevor Transaktion B die Daten aktualisiert, dann wird Transaktion B aktualisiert und festgeschrieben, und Transaktion A liest erneut. Zu diesem Zeitpunkt sind die zweimal gelesenen Daten unterschiedlich. Phantomlesung: (In derselben Transaktion gibt dieselbe Abfrage mehrmals unterschiedliche Ergebnisse zurück. Transaktion B fragt die Anzahl der Datensätze in der Tabelle ab, und dann fügt Transaktion A einen Datensatz in die ein Tabelle, und dann fragt Transaktion B erneut ab und stellt fest, dass die Anzahl der Datensätze unterschiedlich ist. Es gibt viele solcher Erklärungen im Internet, darunter Experten, die meiner Meinung nach aussagekräftiger sind, aber nach Experimenten sind sie nicht korrekt , also muss dies beachtet werden). Sie können ein Experiment wie dieses durchführen. Transaktion A fragt die Anzahl der Datensätze ab, Transaktion B fügt einen Datensatz ein (der Primärschlüsselwert ist 6), führt einen Commit durch und dann fragt Transaktion A die Anzahl der Datensätze ab und stellt fest, dass die Anzahl der Datensätze nicht vorhanden ist geändert, aber zu diesem Zeitpunkt wurde ein Datensatz mit einem Primärschlüsselwert von 6 eingefügt. Es wurde festgestellt, dass die Datensätze widersprüchlich waren, und es fühlte sich wie eine Halluzination an. 1. Dirty Read und nicht wiederholbarer Read: Dirty Read liegt vor, wenn eine Transaktion aktualisierte Daten einer nicht festgeschriebenen Transaktion liest. Nicht wiederholbares Lesen bedeutet, dass die in derselben Transaktion mehrmals gelesenen Daten unterschiedlich sind. 2. Der Unterschied zwischen nicht wiederholbarem Lesen und Phantom-Lesen: Ersteres unterscheidet sich darin, dass die Daten mehrmals gelesen werden, und letzteres ist der Gesamtunterschied beim Lesen der Daten in mehreren Schritten mal.
Änderungen der Isolationsstufe wirken sich auf den Sperrzyklus aus MySQL unterstützt die oben genannten 4 Isolationsstufen und die Standardeinstellung ist wiederholbar lesen
MySQL hat drei Sperrstufen: Ebene , Tabellenebene, Zeilenebene. Die MyISAM- und MEMORY-Speicher-Engines verwenden Sperren auf Tabellenebene. Die BDB-Speicher-Engine verwendet Sperren auf Tabellenebene Die InnoDB-Speicher-Engine unterstützt sowohl Sperren auf Zeilenebene als auch Sperren auf Tabellenebene, verwendet jedoch standardmäßig Sperren auf Zeilenebene. Die Eigenschaften dieser drei Sperren in MySQL lassen sich grob wie folgt zusammenfassen: 1. Sperren auf Tabellenebene: geringer Overhead, keine Deadlocks; höchste Wahrscheinlichkeit von Sperrenkonflikten, niedrigste hohe Parallelität . Sperren auf Tabellenebene ermöglichen es mehreren Threads, gleichzeitig Daten aus der Datentabelle zu lesen. Wenn jedoch ein anderer Thread Daten schreiben möchte, muss er zunächst exklusiven Zugriff erhalten (exklusive Tabellensperre ist standardmäßig hinzugefügt). Lesesperre) ) Beim Aktualisieren von Daten müssen andere Threads warten, bis die Aktualisierung abgeschlossen ist, bevor andere Threads auf die Tabelle zugreifen (lesen) können (exklusive Schreibsperre) 2. Sperre auf Zeilenebene: hoher Overhead und langsame Sperre ; Deadlock wird auftreten; die Sperrgranularität ist am geringsten, die Parallelität ist am höchsten 3、页面锁:开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般。 原则上数据表有一个读锁时,其它进程无法对此表进行更新操作,但在一定条件下,MyISAM表也支持查询和插入操作的并发进行。 一般MyISAM引擎的表也支持查询和插入操作的并发进行(原则上数据表有一个读锁时,其它进程无法对此表进行更新操作) MyISAM引擎有一个系统变量concurrent_insert,专门用以控制其并发插入的行为,其值分别可以为0、1或2: 如果有读写请求同时进行的话,MYSQL将会优先执行写操作。这样MyISAM表在进行大量的更新操作时(特别是更新的字段中存在索引的情况下),会造成查询操作很难获得读锁,从而导致查询阻塞。 我们还可以调整MyISAM读写的优先级别: MyISAM使用的是 flock 类的函数,直接就是对整个文件进行锁定(叫做文件锁定),MyISAM的数据表是按照单个文件存储的,可以针对单个表文件进行锁定; InnoDB使用的是 fcntl 类的函数,可以对文件中局部数据进行锁定(叫做行锁定),InnoDB是一整个文件,把索引、数据、结构全部保存在 ibdata 文件里,所以必须用行锁定。 事物控制语句: MYSQL 事务处理主要有两种方法: 1、用 BEGIN, ROLLBACK, COMMIT来实现 2、直接用 SET 来改变 My SQL 的自动提交模式: 注意点 1、如果事务中sql正确运行,后面没有commit,结果是不会更新到数据库的,所以需要手动添加commit。 2、如果事务中部分sql语句出现错误,那么错误语句后面不会执行。而我们可能会认为正确操作会回滚撤销,但是实际上并没有撤销正确的操作,此时如果再无错情况下进行一次commit,之前的正确操作会生效,数据库会进行更新。1、最左前缀
2、带索引的模糊查询优化
SELECT * FROM tablename MATCH(index_colum) ANGAINST(‘word’);
事务介绍
Unterschiede
Isolationsstufe
a、concurrent_insert为0,不允许并发插入。
b、concurrent_insert为1,如果MyISAM表中没有空洞(即表的中间没有被删除的行),MyISAM允许在一个进程读表的同时,另一个进程从表尾插入记录。这也是MySQL的默认设置。
c、concurrent_insert为2,无论MyISAM表中有没有空洞,都允许在表尾并发插入记录。
a、通过指定启动参数low-priority-updates,使MyISAM引擎默认给予读请求以优先的权利。
b、通过执行命令SET LOW_PRIORITY_UPDATES=1,使该连接发出的更新请求优先级降低。
c、通过指定INSERT、UPDATE、DELETE语句的LOW_PRIORITY属性,降低该语句的优先级。
BEGIN或START TRANSACTION;显式地开启一个事务;
COMMIT;也可以使用COMMIT WORK,不过二者是等价的。
COMMIT会提交事务,并使已对数据库进行的所有修改称为永久性的;
ROLLBACK;有可以使用ROLLBACK WORK,不过二者是等价的。回滚会结束用户的事务,并撤销正在进行的所有未提交的修改;
SAVEPOINT identifier;SAVEPOINT允许在事务中创建一个保存点,一个事务中可以有多个SAVEPOINT;
RELEASE SAVEPOINT identifier;删除一个事务的保存点,当没有指定的保存点时,执行该语句会抛出一个异常;
ROLLBACK TO identifier;把事务回滚到标记点;
SET TRANSACTION;用来设置事务的隔离级别。
InnoDB存储引擎提供事务的隔离级别有READ UNCOMMITTED、READ COMMITTED、REPEATABLE READ和SERIALIZABLE。
BEGIN 开始一个事务
ROLLBACK 事务回滚
COMMIT 事务确认
SET AUTOCOMMIT=0 禁止自动提交
SET AUTOCOMMIT=1 开启自动提交
Das obige ist der detaillierte Inhalt vonDetaillierte Interpretation von MySQL-Indizes und -Transaktionen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!