Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Indexerstellung beschleunigen

23 views
Skip to first unread message

Carsten Mueller

unread,
Dec 15, 2009, 4:45:07 AM12/15/09
to
Hi NG,

ich habe ein Problem:

Die Erstellung meiner Indices dauert viel zu lange. Was kann ich noch
versuchen, um es zu beschleunigen?

*************************** 1. row ***************************
Id: 14
User: worker
Host: sqlserver:57798
db: mydata
Command: Query
Time: 65417
State: Repair with keycache
Info: ALTER TABLE tab ADD INDEX quality (quality)

In der Tabelle sind 11 Mio. Datensaetze. Wenn ich das jetzt einfach
weiterlaufen lasse, braucht mysqld deutlich ueber 100000 Sekunden um den Index
zu erstellen (und ich habe mehrere davon).

OS: MacOS X 10.4.11 (32-Bit)
FS: HFS+
HD: SATA2
CPU: 2 x Intel(R) Xeon(R) CPU E5462 @ 2.80GHz
RAM: 4 GB
Server version: 5.0.45-log Source distribution

Das ist die Tabellendefinition:

CREATE TABLE `tab` (
`db` varbinary(30) NOT NULL,
`seq` varbinary(20) NOT NULL,
`qlen` int(10) unsigned NOT NULL,
`qname` varbinary(255) NOT NULL,
`hname` varbinary(255) NOT NULL,
`pctident` float unsigned NOT NULL,
`hlenq` int(10) unsigned NOT NULL,
`z2` int(10) unsigned NOT NULL,
`z3` int(10) unsigned NOT NULL,
`qstart` int(10) unsigned NOT NULL,
`qstop` int(10) unsigned NOT NULL,
`hstart` int(10) unsigned NOT NULL,
`hstop` int(10) unsigned NOT NULL,
`expect` double unsigned NOT NULL,
`score` double unsigned NOT NULL,
`stage` int(10) unsigned NOT NULL,
`quality` int(10) unsigned NOT NULL,
`gi` int(10) unsigned default NULL,
`ctg` varbinary(20) default NULL,
`geno` varbinary(10) default NULL,
KEY `db` (`db`),
KEY `qname` (`qname`),
KEY `stage` (`stage`),
KEY `qstart` (`qstart`),
KEY `pctident` (`pctident`)
) ENGINE=MyISAM DEFAULT CHARSET=ascii COLLATE=ascii_bin

Das ist die Konfiguration:
[mysqld]
skip-external-locking
open_files_limit = 2048
max_allowed_packet = 64M
key_buffer = 512M
table_cache = 512
sort_buffer_size = 4M
read_buffer_size = 4M
read_rnd_buffer_size = 8M
myisam_sort_buffer_size = 512M
thread_concurrency = 8
max_allowed_packet = 64M
thread_stack = 128K
thread_cache_size = 8
query_cache_limit = 1048576
query_cache_size = 32M
query_cache_type = 1
log_slow_queries = /var/log/mysql-slow.log
skip-bdb
skip-innodb

Irgendwelche Ideen?

MfG
MdC

Andreas Kretschmer

unread,
Dec 15, 2009, 5:07:18 AM12/15/09
to
Carsten Mueller <cmue...@chronixbiomedical.de> wrote:
> Hi NG,
>
> ich habe ein Problem:
>
> Die Erstellung meiner Indices dauert viel zu lange. Was kann ich noch
> versuchen, um es zu beschleunigen?

Was ist das Problem dabei, daᅵ die Tabelle gesperrt ist?

CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] name ON table
^^^^^^^^^^^^

CONCURRENTLY

When this option is used, PostgreSQL will build the index without
taking any locks that prevent concurrent inserts, updates, or deletes on
the table;


Ach so, Du hast MySQL?

Andreas
--
Andreas Kretschmer
Linux - weil ich es mir wert bin!
GnuPG-ID 0x3FFF606C http://wwwkeys.de.pgp.net

Carsten Mueller

unread,
Dec 15, 2009, 6:48:42 AM12/15/09
to
Andreas Kretschmer wrote:

> Carsten Mueller <cmue...@chronixbiomedical.de> wrote:
>> Die Erstellung meiner Indices dauert viel zu lange. Was kann ich noch
>> versuchen, um es zu beschleunigen?
>
> Was ist das Problem dabei, daᅵ die Tabelle gesperrt ist?

Nein, sie ist nicht gesperrt. Es finden keinerlei sonstige Operationen auf der
Datenbank statt.

> ...


> Ach so, Du hast MySQL?

Ja, wie in dieser Gruppe zu erwarten :-)

MfG
MdC

Axel Schwenke

unread,
Dec 15, 2009, 7:07:44 AM12/15/09
to
Carsten Mueller <cmue...@chronixbiomedical.de> wrote:
>
> Die Erstellung meiner Indices dauert viel zu lange. Was kann ich noch
> versuchen, um es zu beschleunigen?
>
> *************************** 1. row ***************************
> Id: 14
> User: worker
> Host: sqlserver:57798
> db: mydata
> Command: Query
> Time: 65417
> State: Repair with keycache
~~~~~~~~~~~~~~~~~~~~

> Info: ALTER TABLE tab ADD INDEX quality (quality)

Ich habe das Problem mal unterstrichen.

MyISAM hat zwei Methoden um einen Index aufzubauen/zu reparieren.
Die schnellere Methode ist "repair with sorting". F�r die Sortierung
wesentliche Server-Variablen sind

> myisam_sort_buffer_size = 512M

ist f�r mein Gef�hl aber zu gro�, nimm eher so 64M

und myisam_max_sort_file_size, hast du nicht gesetzt, also default 2G.
Wenn MyISAM sch�tzt, da� das tempor�re sortfile gr��er werden k�nnte,
als obige Variable, dann wird die langsamere keycache-Methode
verwendet.

Zur Absch�tzung wird folgendes verwendet:

2 * num_rows * (index_length + row_pointer_size)

index_length ist die Summe der maximalen L�ngen der Felder im Index
(also f�r VARCHAR(255) = 255). Der Row pointer hat normal 6 Bytes.

Ich empfehle also, myisam_max_sort_file_size passend zu setzen und
nat�rlich auch entsprechend Platz im tmpdir (MySQL variable, default
ist das System-Tempdir) zu haben.

Da 2 * 10.000.000 * (4+6) << 2G k�nnte es sein, da� bei dir MyISAM
schonmal das tmpdir gef�llt hat und dann auf "repair with keycache"
ausgewichen ist.


XL

Carsten Mueller

unread,
Dec 15, 2009, 7:51:54 AM12/15/09
to
Axel Schwenke wrote:
> Carsten Mueller <cmue...@chronixbiomedical.de> wrote:
>> Die Erstellung meiner Indices dauert viel zu lange. Was kann ich noch
>> versuchen, um es zu beschleunigen?
>>
>> State: Repair with keycache

>> Info: ALTER TABLE tab ADD INDEX quality (quality)
> MyISAM hat zwei Methoden um einen Index aufzubauen/zu reparieren.
> Die schnellere Methode ist "repair with sorting". F�r die Sortierung
> wesentliche Server-Variablen sind
>> myisam_sort_buffer_size = 512M
> ist f�r mein Gef�hl aber zu gro�, nimm eher so 64M

Dann werden aber andere Operationen wieder langsamer :-(

> und myisam_max_sort_file_size, hast du nicht gesetzt, also default 2G.

ja, steht auf 2GB

> Wenn MyISAM sch�tzt, da� das tempor�re sortfile gr��er werden k�nnte,
> als obige Variable, dann wird die langsamere keycache-Methode
> verwendet.
>
> Zur Absch�tzung wird folgendes verwendet:
> 2 * num_rows * (index_length + row_pointer_size)
> index_length ist die Summe der maximalen L�ngen der Felder im Index
> (also f�r VARCHAR(255) = 255). Der Row pointer hat normal 6 Bytes.
>
> Ich empfehle also, myisam_max_sort_file_size passend zu setzen

Das sind dann 2 * 11.000.000 * (4+6) = 220.000.000 ~= 210 MB
mit sizeof( INT(10) ) == 4
bzw.
2 * 11.000.000 * (255+6) = 5.742.000.000 ~= 5,4 GB

Nach dieser Rechnung sollte der Vorgabewert von 2GB doch fuer `quality`
reichen, fuer `qname` nicht. Nur ist leider 2GB das Maximum.

mysql> set global myisam_max_sort_file_size = 6442450944;
Query OK, 0 rows affected (0.00 sec)

mysql> show variables like "myisam_max_sort_file_size";
+---------------------------+------------+
| Variable_name | Value |
+---------------------------+------------+
| myisam_max_sort_file_size | 2147483647 |
+---------------------------+------------+
1 row in set (0.00 sec)

> und
> nat�rlich auch entsprechend Platz im tmpdir (MySQL variable, default
> ist das System-Tempdir) zu haben.

tmpdir ist "/tmp" und da sind 270 GB frei.

> Da 2 * 10.000.000 * (4+6) << 2G k�nnte es sein, da� bei dir MyISAM
> schonmal das tmpdir gef�llt hat und dann auf "repair with keycache"
> ausgewichen ist.

Kann sowas bei einer vorherigen Operation (CREATE TABLE xy SELECT DISTINCT *
FROM tab) sich wirklich auf die Indexerstellung auswirken?

MfG
MdC

Axel Schwenke

unread,
Dec 15, 2009, 8:25:27 AM12/15/09
to
Carsten Mueller <cmue...@chronixbiomedical.de> wrote:
> Axel Schwenke wrote:

>>> myisam_sort_buffer_size = 512M
>> ist f�r mein Gef�hl aber zu gro�, nimm eher so 64M
>
>Dann werden aber andere Operationen wieder langsamer :-(

Nein. Der MyISAM sort-buffer wird ausschlie�lich f�r das Erzeugen
oder Reparieren von MyISAM-Indizes (nach der sort-Methode) verwendet.
Was du vermutlich meinst, ist key_buffer_size.

>> ... myisam_max_sort_file_size, hast du nicht gesetzt, also default 2G.
...


>> 2 * num_rows * (index_length + row_pointer_size)
>> index_length ist die Summe der maximalen L�ngen der Felder im Index
>> (also f�r VARCHAR(255) = 255). Der Row pointer hat normal 6 Bytes.
>>
>> Ich empfehle also, myisam_max_sort_file_size passend zu setzen
>
> Das sind dann 2 * 11.000.000 * (4+6) = 220.000.000 ~= 210 MB
> mit sizeof( INT(10) ) == 4
> bzw.
> 2 * 11.000.000 * (255+6) = 5.742.000.000 ~= 5,4 GB

Ja.

> Nach dieser Rechnung sollte der Vorgabewert von 2GB doch fuer `quality`
> reichen, fuer `qname` nicht.

Jein. Und Ja :)

> Nur ist leider 2GB das Maximum.

Nein.

> mysql> set global myisam_max_sort_file_size = 6442450944;

> mysql> show variables like "myisam_max_sort_file_size";

Du machst SET GLOBAL und SHOW (ohne GLOBAL)

Der globale Wert wird erst f�r neue Sessions wirksam. Alternativ
kannst du auch nur den lokalen Wert setzen.

> tmpdir ist "/tmp" und da sind 270 GB frei.

Gut.

>> Da 2 * 10.000.000 * (4+6) << 2G k�nnte es sein, da� bei dir MyISAM
>> schonmal das tmpdir gef�llt hat und dann auf "repair with keycache"
>> ausgewichen ist.
>
> Kann sowas bei einer vorherigen Operation (CREATE TABLE xy SELECT DISTINCT *
> FROM tab) sich wirklich auf die Indexerstellung auswirken?

Eher nicht, weil diese Query keinen Platz in tmpdir braucht.

Dein Problem ist glaube ich die ineffiziente Implementierung von
ALTER TABLE. Es wird eine Kopie deiner Tabelle angelegt und *alle*
Indizes auf dieser Kopie neu aufgebaut (einer nach dem anderen).
Das ALTER TABLE k�nnte also gerade in der Phase sein, wo der Index
auf (qname) neu gebaut wird.


XL

Christian Kirsch

unread,
Dec 15, 2009, 10:49:12 AM12/15/09
to
Am 15.12.09 10:45, schrieb Carsten Mueller:

Unabhᅵngig von allem anderen kᅵnntest Du ᅵberlegen, ob die Schlᅵssel auf
qname und pctident in dieser Form sinnvoll sind. 255 Zeichen lange
Schlᅵssel dᅵrften auch im normalen Betrieb nicht besonders
leistungsfᅵhig sein. Du kᅵnntest entweder die Grᅵᅵe des Index
beschrᅵnken (also z.B. nur die ersten x Zeichen von qname verwenden)
oder einen Hashwert von qname einfᅵhren (dafᅵr brauchst Du dann UPDATE-
und INSERT-Trigger), auf den Du den Index legst.

Der Index auf pctident, also einen FLOAT-Wert, kommt mir komisch vor.
Auf die Schnelle habe ich dazu das hier gefunden:
http://support.microsoft.com/kb/128809
Ich wᅵrde mich unwohl fᅵhlen bei der Vorstellung, dass MySQL Wert
miteinander vergleichen soll, die es per definitionem nicht in jedem
Fall exakt darstellen kann. YMMV.

Carsten Mueller

unread,
Dec 17, 2009, 10:05:23 AM12/17/09
to
Axel Schwenke wrote:
> Carsten Mueller <cmue...@chronixbiomedical.de> wrote:
>> Axel Schwenke wrote:
>
>>>> myisam_sort_buffer_size = 512M
>>> ist f�r mein Gef�hl aber zu gro�, nimm eher so 64M
>> Dann werden aber andere Operationen wieder langsamer :-(
> Nein. Der MyISAM sort-buffer wird ausschlie�lich f�r das Erzeugen
> oder Reparieren von MyISAM-Indizes (nach der sort-Methode) verwendet.
> Was du vermutlich meinst, ist key_buffer_size.

Ok, das war mir so nicht klar.

>>> 2 * num_rows * (index_length + row_pointer_size)
>>> index_length ist die Summe der maximalen L�ngen der Felder im Index
>>> (also f�r VARCHAR(255) = 255). Der Row pointer hat normal 6 Bytes.
>>> Ich empfehle also, myisam_max_sort_file_size passend zu setzen
>> Das sind dann 2 * 11.000.000 * (4+6) = 220.000.000 ~= 210 MB
>> mit sizeof( INT(10) ) == 4
>> bzw.
>> 2 * 11.000.000 * (255+6) = 5.742.000.000 ~= 5,4 GB
> Ja.
>> Nach dieser Rechnung sollte der Vorgabewert von 2GB doch fuer `quality`
>> reichen, fuer `qname` nicht.
>
> Jein. Und Ja :)

Wieso "Jein" ?

>> Nur ist leider 2GB das Maximum.
> Nein.
>> mysql> set global myisam_max_sort_file_size = 6442450944;
>> mysql> show variables like "myisam_max_sort_file_size";
> Du machst SET GLOBAL und SHOW (ohne GLOBAL)
> Der globale Wert wird erst f�r neue Sessions wirksam. Alternativ
> kannst du auch nur den lokalen Wert setzen.

Wie?
mysql> set session myisam_max_sort_file_size = 2147483648;
ERROR 1229 (HY000): Variable 'myisam_max_sort_file_size' is a GLOBAL variable
and should be set with SET GLOBAL
mysql> set myisam_max_sort_file_size = 2147483648;
ERROR 1229 (HY000): Variable 'myisam_max_sort_file_size' is a GLOBAL variable
and should be set with SET GLOBAL

> Dein Problem ist glaube ich die ineffiziente Implementierung von
> ALTER TABLE. Es wird eine Kopie deiner Tabelle angelegt und *alle*
> Indizes auf dieser Kopie neu aufgebaut (einer nach dem anderen).

Ups, ist das wirklich so? Wenn ich einen neuen Index erstelle, kopiert mysql
die Tabelle, erstellt (auf der Kopie) alle bisher bestehenden Indices und
fuegt dann den neuen Index hinzu? Das waere allerdings eine ziemlich
ineffiziente Implementierung :-(

MfG
MdC

Carsten Mueller

unread,
Dec 17, 2009, 10:20:25 AM12/17/09
to
Christian Kirsch wrote:
> Am 15.12.09 10:45, schrieb Carsten Mueller:
>
>> Das ist die Tabellendefinition:
>>
>> CREATE TABLE `tab` (
>> ...
>> `qname` varbinary(255) NOT NULL,
>> ...

>> `pctident` float unsigned NOT NULL,
>> ...

>> KEY `qname` (`qname`),
>> ...

>> KEY `pctident` (`pctident`)
>> ) ENGINE=MyISAM DEFAULT CHARSET=ascii COLLATE=ascii_bin
>>
> Unabhᅵngig von allem anderen kᅵnntest Du ᅵberlegen, ob die Schlᅵssel auf
> qname und pctident in dieser Form sinnvoll sind. 255 Zeichen lange
> Schlᅵssel dᅵrften auch im normalen Betrieb nicht besonders
> leistungsfᅵhig sein.

Ja, aber das ist IMO nicht das Problem. Auch die Erstellung anderer Indices
dauert einfach ewig bei den grossen Datenmengen.

> Du kᅵnntest entweder die Grᅵᅵe des Index
> beschrᅵnken (also z.B. nur die ersten x Zeichen von qname verwenden)
> oder einen Hashwert von qname einfᅵhren (dafᅵr brauchst Du dann UPDATE-
> und INSERT-Trigger), auf den Du den Index legst.

Hmm, da ich von ueber 50 Prozessen parallel in die Datenbank schreibe und
gleich wieder lese (CONCURRENT_INSERT), fuerchte ich dadurch massive
Performanceverluste zu erleiden...

> Der Index auf pctident, also einen FLOAT-Wert, kommt mir komisch vor.
> Auf die Schnelle habe ich dazu das hier gefunden:
> http://support.microsoft.com/kb/128809

Ich sehe keinen Zusammenhang. Ich indiziere ein FLOAT-Feld um es spaeter a la
'WHERE `pctident` > 75' abzufragen.

> Ich wᅵrde mich unwohl fᅵhlen bei der Vorstellung, dass MySQL Wert
> miteinander vergleichen soll, die es per definitionem nicht in jedem
> Fall exakt darstellen kann. YMMV.

Ohne den Index erfolgt ein full-table-scan, mit nicht. Geprueft mittels
"EXPLAIN", die Zahl der zu testenden rows sinkt deutlich.

MfG
MdC

Axel Schwenke

unread,
Dec 17, 2009, 10:56:57 AM12/17/09
to
Carsten Mueller <cmue...@chronixbiomedical.de> wrote:
> Axel Schwenke wrote:

>>> Nach dieser Rechnung sollte der Vorgabewert von 2GB doch fuer `quality`
>>> reichen, fuer `qname` nicht.
>>
>> Jein. Und Ja :)
>
> Wieso "Jein" ?

Ja, wenn wirklich nur dieser Index erzeugt/repariert wird.

>> Du machst SET GLOBAL und SHOW (ohne GLOBAL)
>> Der globale Wert wird erst f�r neue Sessions wirksam. Alternativ
>> kannst du auch nur den lokalen Wert setzen.
>

> mysql> set session myisam_max_sort_file_size = 2147483648;
> ERROR 1229 (HY000): Variable 'myisam_max_sort_file_size' is a GLOBAL variable
> and should be set with SET GLOBAL

�hhm. Mein Fehler. Aber auch wenn du den Wert der Session-Variable
nicht setzen kannst, bleibt immer noch die Tatsache, da� jede
Session ihre eigene Kopie dieser Variable hat. Und die wird beim
Aufbau der Session aus der globalen Variable initialisiert.

Neue Sessions sehen dann auch den neuen Wert von
myisam_max_sort_file_size, genau wie SHOW GLOBAL VARIABLES.

>> Dein Problem ist glaube ich die ineffiziente Implementierung von
>> ALTER TABLE. Es wird eine Kopie deiner Tabelle angelegt und *alle*
>> Indizes auf dieser Kopie neu aufgebaut (einer nach dem anderen).
>
> Ups, ist das wirklich so? Wenn ich einen neuen Index erstelle, kopiert mysql
> die Tabelle, erstellt (auf der Kopie) alle bisher bestehenden Indices und
> fuegt dann den neuen Index hinzu? Das waere allerdings eine ziemlich
> ineffiziente Implementierung :-(

Ja. Das neue InnoDB-Plugin hat ein Feature "online add index", das
genau diesen Fall optimiert. Cluster hat es auch. MyISAM wird es
wohl nie bekommen. Maria evtl. doch. Falls Maria mal fertig wird.


XL

Carsten Mueller

unread,
Dec 22, 2009, 10:54:33 AM12/22/09
to
Axel Schwenke wrote:
> Carsten Mueller <cmue...@chronixbiomedical.de> wrote:
>> Axel Schwenke wrote:
>
>>>> Nach dieser Rechnung sollte der Vorgabewert von 2GB doch fuer `quality`
>>>> reichen, fuer `qname` nicht.
>>> Jein. Und Ja :)
>> Wieso "Jein" ?
> Ja, wenn wirklich nur dieser Index erzeugt/repariert wird.

In dieser Anweisung schon. Danach kommen allerdings noch weiter ALTER TABLE
ADD INDEX.

>>> Du machst SET GLOBAL und SHOW (ohne GLOBAL)
>>> Der globale Wert wird erst f�r neue Sessions wirksam. Alternativ
>>> kannst du auch nur den lokalen Wert setzen.
>> mysql> set session myisam_max_sort_file_size = 2147483648;
>> ERROR 1229 (HY000): Variable 'myisam_max_sort_file_size' is a GLOBAL variable
>> and should be set with SET GLOBAL
>
> �hhm. Mein Fehler. Aber auch wenn du den Wert der Session-Variable
> nicht setzen kannst, bleibt immer noch die Tatsache, da� jede
> Session ihre eigene Kopie dieser Variable hat. Und die wird beim
> Aufbau der Session aus der globalen Variable initialisiert.
>
> Neue Sessions sehen dann auch den neuen Wert von
> myisam_max_sort_file_size, genau wie SHOW GLOBAL VARIABLES.

Ja, hat funktioniert :-)

>>> Dein Problem ist glaube ich die ineffiziente Implementierung von
>>> ALTER TABLE. Es wird eine Kopie deiner Tabelle angelegt und *alle*
>>> Indizes auf dieser Kopie neu aufgebaut (einer nach dem anderen).
>> Ups, ist das wirklich so? Wenn ich einen neuen Index erstelle, kopiert mysql
>> die Tabelle, erstellt (auf der Kopie) alle bisher bestehenden Indices und
>> fuegt dann den neuen Index hinzu? Das waere allerdings eine ziemlich
>> ineffiziente Implementierung :-(
>
> Ja. Das neue InnoDB-Plugin hat ein Feature "online add index", das
> genau diesen Fall optimiert. Cluster hat es auch. MyISAM wird es
> wohl nie bekommen. Maria evtl. doch. Falls Maria mal fertig wird.

Tja, ich bin aber leider auf CONCURRENT_INSERT angewiesen, und da muss InnoDB
IMO passen. Wie es mit den anderen Engines ist, weiss ich nicht.

> XL

Danke fuer die Tips und Infos!

MfG
MdC

Axel Schwenke

unread,
Dec 22, 2009, 11:28:10 AM12/22/09
to

�hm. Hallo? InnoDB kann selbstverst�ndlich concurrent insert.
Und noch viel mehr. Das ist eine MVCC engine. So richtig mit
transaction isolation und allem drum und dran.


XL

Carsten Mueller

unread,
Dec 23, 2009, 4:35:48 AM12/23/09
to
Axel Schwenke wrote:
> Carsten Mueller <cmue...@chronixbiomedical.de> wrote:
>> Tja, ich bin aber leider auf CONCURRENT_INSERT angewiesen, und da
>> muss InnoDB IMO passen.
>
> �hm. Hallo? InnoDB kann selbstverst�ndlich concurrent insert.

Echt? Ich habe meine Weisheit hier bezogen:
http://dev.mysql.com/doc/refman/5.0/en/concurrent-inserts.html
Und da steht nix von InnoDB.

> Und noch viel mehr. Das ist eine MVCC engine. So richtig mit
> transaction isolation und allem drum und dran.

Ja, aber sooo wichtig sind mir Transaktionen nicht.

Also das mit den CONCURRENT_INSERTS interessiert mich schon. Ich brauche jede
Menge Performance und habe viele(!) gleichzeitige INSERTS und SELECTS (von
diversen parallelen Prozessen). Wenn die fertig sind kommen die ALTER TABLE
ADD INDEX aus meinem Ursprungsposting.

Ist das mit InnoDB und concurrent inserts irgendwo dokumentiert? Hast du ggf.
einen Link fuer mich? Am liebsten mit Performancevergleich MyISAM <-> InnoDB
bei concurrent inserts.

MfG
MdC

Axel Schwenke

unread,
Dec 28, 2009, 11:19:09 AM12/28/09
to
Carsten Mueller <cmue...@chronixbiomedical.de> wrote:
> Axel Schwenke wrote:
>> Carsten Mueller <cmue...@chronixbiomedical.de> wrote:
>>> Tja, ich bin aber leider auf CONCURRENT_INSERT angewiesen, und da
>>> muss InnoDB IMO passen.
>>
>> �hm. Hallo? InnoDB kann selbstverst�ndlich concurrent insert.
>
> Echt? Ich habe meine Weisheit hier bezogen:
> http://dev.mysql.com/doc/refman/5.0/en/concurrent-inserts.html
> Und da steht nix von InnoDB.

Weil InnoDB eben noch viel mehr kann. "Concurrent Insert" ist eine
winzige Verbesserung gegen�ber dem sonstigen "nur 1 Writer _oder_
ein bis mehrere Reader auf einer Tabelle" bei MyISAM. Mit "Concurrent
Insert" erlaubt MyISAM in engen Grenzen einen(!) zus�tzlichen Writer
neben den Readern.

Bei InnoDB k�nnen beliebig viele Connections gleichzeitig auf die
gleiche Tabelle zugreifen. Lesen praktisch immer [1] Schreiben
nat�rlich nur auf verschiedene Datens�tze. Und entgegen den Dar-
stellungen in machen Blogs (habe gerade beim Googlen eins gesehen)
kann eine Connection auch auf einen Record zugreifen, der gerade in
einer anderen Connection UPDATEd oder gar DELETEd wird. Je nach
Transaction-Isolationslevel sieht der Reader entweder den alten
oder den neuen Zustand.

[1] Ausnahme: bei INSERT ... SELECT wird das SELECT wie SELECT ...
FOR UPGRADE gehandhabt. Das wird so gebraucht, weil das Statement
sonst nicht replizierbar w�re. Und es gibt SELECT mit explizitem Lock

>> Und noch viel mehr. Das ist eine MVCC engine. So richtig mit
>> transaction isolation und allem drum und dran.
>
> Ja, aber sooo wichtig sind mir Transaktionen nicht.
>
> Also das mit den CONCURRENT_INSERTS interessiert mich schon. Ich brauche jede
> Menge Performance und habe viele(!) gleichzeitige INSERTS und SELECTS (von
> diversen parallelen Prozessen). Wenn die fertig sind kommen die ALTER TABLE
> ADD INDEX aus meinem Ursprungsposting.

Genau diese Art von Workload - gemischter Schreib/Lesebetrieb auf
den gleichen Tabellen - ist eine gro�e St�rke von InnoDB. Bei INSERT
lauert noch eine Falle: die Erzeugung von AUTO_INCREMENT-Nummern wird
immer serialisiert. Zwei INSERTs auf die gleiche Tabelle, die jeweils
eine Id erzeugen, macht InnoDB also immer nur nacheinander. In 5.1 ist
das nochmal verbessert worden.

> Ist das mit InnoDB und concurrent inserts irgendwo dokumentiert? Hast du ggf.
> einen Link fuer mich?

Das Handbuch. Am besten liest du komplett:
http://dev.mysql.com/doc/refman/5.1/en/innodb.html

der interessante Teil bez�glich Locking ist hier:
http://dev.mysql.com/doc/refman/5.1/en/innodb-transaction-model.html

im Vergleich dazu das table-level locking von MyISAM:
http://dev.mysql.com/doc/refman/5.1/en/internal-locking.html

Lock-Contention ist *das* typische Performance-Problem mit MyISAM.
Hier ist eine Liste von Abhilfen. "silver bullet" ist "nutze InnoDB"
http://dev.mysql.com/doc/refman/5.1/en/table-locking.html


> Am liebsten mit Performancevergleich MyISAM <-> InnoDB
> bei concurrent inserts.

Benchmarks aus diesem Bereich habe ich gerade nicht bei der Hand.
Aber Google sollte da genug finden, Kanonische Anlaufstelle ist
www.mysqlperformanceblog.com. Z.B. gibts da auch einen Artikel der
der Frage nachgeht, ob man zu InnoDB wechseln sollte:

http://www.mysqlperformanceblog.com/2009/01/12/should-you-move-from-myisam-to-innodb/

Ansonsten ist das eigentlich allgemein bekannt, da� MyISAM ein
Locking-Problem bei konkurrierenden Schreibzugriffen hat.


XL

Thomas Rachel

unread,
Dec 28, 2009, 3:45:30 PM12/28/09
to
Am 15.12.2009 16:49, schrieb Christian Kirsch:

> Der Index auf pctident, also einen FLOAT-Wert, kommt mir komisch vor.
> Auf die Schnelle habe ich dazu das hier gefunden:
> http://support.microsoft.com/kb/128809

> Ich würde mich unwohl fühlen bei der Vorstellung, dass MySQL Wert


> miteinander vergleichen soll, die es per definitionem nicht in jedem
> Fall exakt darstellen kann. YMMV.

Warum? Solange kein Test auf Gleichheit stattfindet (was in der Tat
ungünstig wäre), paßts doch.


Thomas

0 new messages