heap table und log_slow_queries

heap table und log_slow_queries

am 18.01.2008 21:24:11 von Andreas Born

Hallo,

ich komme gerade bei einer Sache nicht weiter. Und zwar bin ich gerade
dabei, mein slow-query-log zu analysieren, das auch alle Abfragen
enthält, bei denen kein Index verwendet werden konnte.

Nun habe ich eine kleine Heap-Tabelle, die sehr oft verwendet wird und
dabei immer komplett eingelesen wird, d.h. es werden alle rows benötigt
und zurückgeliefert. Schematisch:

CREATE TABLE `heap_table` (
`id` int(10) unsigned NOT NULL default '0',
`value` varchar(100) NOT NULL default '',
PRIMARY KEY (`id`),
KEY `value` (`value`(40))
) ENGINE=HEAP DEFAULT CHARSET=utf8 PACK_KEYS=1;

SELECT `id`,`value` FROM `heap_table` ORDER BY `value`;


Nun würde ich eigentlich annehmen, daß zu diesem Statement der Index
über value herangezogen wird (zum sortieren), aber ein explain zeigt daß
dem nicht so ist. Stattdessen ist possible_keys NULL und sortiert wird
mittels filesort. Was übersehe ich hier? Kann der Index einer Heap-Table
nicht zum sortieren verwendet werden?

Wenn das so ist, ok. Also neue Abfrage:

SELECT `id`,`value` FROM `heap_table` WHERE `id` >= 0 ORDER BY `value`;

Spätestens jetzt würde ich erwarten, daß zumindst der Primary Key
verwendet wird. Dem ist auch so, aber das Statement taucht trotzdem im
slow_query_log auf.

Wie kann ich diese Abfrage aus dem log verbannen oder entsprechend
anpassen?

Wenn zum sortieren eh kein Index verwendet wird, macht es dann überhaupt
Sinn eine heap-Tabelle zu verwenden?


Viele Grüße,
Andreas

Re: heap table und log_slow_queries

am 21.01.2008 17:34:18 von Axel Schwenke

Andreas Born wrote:

> CREATE TABLE `heap_table` (
> `id` int(10) unsigned NOT NULL default '0',
> `value` varchar(100) NOT NULL default '',
> PRIMARY KEY (`id`),
> KEY `value` (`value`(40))
> ) ENGINE=3DHEAP DEFAULT CHARSET=3Dutf8 PACK_KEYS=3D1;
>=20
> SELECT `id`,`value` FROM `heap_table` ORDER BY `value`;
>=20
> Nun würde ich eigentlich annehmen, daß zu diesem Statement der Inde=
x
> über value herangezogen wird (zum sortieren), aber ein explain zeigt =
daß
> dem nicht so ist. Stattdessen ist possible_keys NULL und sortiert wird
> mittels filesort.=20

Ja.

> Was übersehe ich hier?=20

Daß HEAP-Tabellen (heißen übrigens schon seit Ewigkeiten MEMORY)
defaultmäßig einen HASH Index bekommen, aber auch BTREE können.

> Kann der Index einer Heap-Table
> nicht zum sortieren verwendet werden?

Nicht wenn es ein Hashindex ist.

> Wenn das so ist, ok. Also neue Abfrage:
>=20
> SELECT `id`,`value` FROM `heap_table` WHERE `id` >=3D 0 ORDER BY `value=
`;
>=20
> Spätestens jetzt würde ich erwarten, daß zumindst der Primary Key=

> verwendet wird. Dem ist auch so, aber das Statement taucht trotzdem im
> slow_query_log auf.

Bei einem INT UNSIGNED ist '>=3D 0' nicht wirklich eine Einschränkung.
Wenn sowieso alle Zeilen der Tabelle gebraucht werden, ist ein tablescan
schneller als ein Indexzugriff. Bzw. bei einer MEMORY Tabelle sowieso
weitgehend egal.

> Wie kann ich diese Abfrage aus dem log verbannen=20

Gar nicht. --log-queries-not-using-indexes liefert prinzipbedingt viele
false positives. Z.B. immer dann, wenn eine Tabelle fast leer ist oder
ohnehin die meisten Zeilen gebraucht werden.

Besser wäre --log-queries-not-using-indexes-and-query-cost-higher-than=3 D=
..
Gibts aber (zumindest derzeit) nicht.

Ein Workaround besteht darin, bekannte Queries, die fälschlich im slow-=
log
landen, per /* SQL-Kommentar */ zu taggen und später automatisiert aus =
dem
slow-log zu werfen.


XL
--=20
In der klassischen Kryptographie verschlüsselt Alice Nachrichten an Bob=
um
sie vor Carol zu schützen. Bei DRM sind Bob und Carol die gleiche Perso=
n.

Re: heap table und log_slow_queries

am 25.01.2008 23:37:36 von Andreas Born

Axel Schwenke wrote:

> Andreas Born wrote:
>> CREATE TABLE `heap_table` (
>> `id` int(10) unsigned NOT NULL default '0',
>> `value` varchar(100) NOT NULL default '',
>> PRIMARY KEY (`id`),
>> KEY `value` (`value`(40))
>> ) ENGINE=HEAP DEFAULT CHARSET=utf8 PACK_KEYS=1;
>>
>> SELECT `id`,`value` FROM `heap_table` ORDER BY `value`;
>>
>> Nun würde ich eigentlich annehmen, daß zu diesem Statement der Index
>> über value herangezogen wird (zum sortieren), aber ein explain zeigt
>> daß dem nicht so ist. Stattdessen ist possible_keys NULL und sortiert
>> wird mittels filesort.
>
> Ja.
>
>> Was übersehe ich hier?
>
> Daß HEAP-Tabellen (heißen übrigens schon seit Ewigkeiten MEMORY)
> defaultmäßig einen HASH Index bekommen, aber auch BTREE können.

Ok, dachte ich mir schon fast.
Wie muß ich die Tabelle erstellen, damit BTREE verwendet wird?

>> Kann der Index einer Heap-Table nicht zum sortieren verwendet werden?
>
> Nicht wenn es ein Hashindex ist.

Dann bringt ein solcher Index aber nur etwas, wenn man gezielt genau auf
einen Datensatz zugreifen möchte. Was soll dann der Vorteil eines
gehash'ten Indexes sein?

>> SELECT `id`,`value` FROM `heap_table` WHERE `id` >= 0 ORDER BY
>> `value`;
>>
>> Spätestens jetzt würde ich erwarten, daß zumindst der Primary Key
>> verwendet wird. Dem ist auch so, aber das Statement taucht trotzdem
>> im slow_query_log auf.
>
> Bei einem INT UNSIGNED ist '>= 0' nicht wirklich eine Einschränkung.
> Wenn sowieso alle Zeilen der Tabelle gebraucht werden, ist ein
> tablescan schneller als ein Indexzugriff. Bzw. bei einer MEMORY
> Tabelle sowieso weitgehend egal.

Ok, MySQL lässt sich also nicht so einfach austricksen *g* ;-)

>> Wie kann ich diese Abfrage aus dem log verbannen
>
> Gar nicht. --log-queries-not-using-indexes liefert prinzipbedingt
> viele false positives. Z.B. immer dann, wenn eine Tabelle fast leer
> ist oder ohnehin die meisten Zeilen gebraucht werden.
>
> Besser wäre
> --log-queries-not-using-indexes-and-query-cost-higher-than=. ..
> Gibts aber (zumindest derzeit) nicht.
>
> Ein Workaround besteht darin, bekannte Queries, die fälschlich im
> slow-log landen, per /* SQL-Kommentar */ zu taggen und später
> automatisiert aus dem slow-log zu werfen.

Vielen Dank, sehr gute Idee!


Viele Grüße,
Andreas