mysql subqueries bug

Setelah projek pkaji, kami cuba menambahkan maklumat/profile untuk setiap serangan RFI.

Ketika menulis kod untuk menggali maklumat yang tersimpan dalam database yang mempunyai hubungan many-to-many, didapati mysql mengambil masa yang terlalu panjang.

Dari penilitian yang dibuat, sql yang paling luar ketika penggunaan subqueries tidak optimize kerana enjin mysql gagal menggunakan index yang sesuai.

Kod yang berkenaan adalah untuk paparkan senarai url setiap kod RFI yang pernah digunakan oleh ip(attacker) tertentu.

Maklumat berkenaan tersimpan dalam 3 table, event, event2rfi dan rfi. Di sini event dan rfi mempunyai hubungan many-to-many. Maka event2rfi adalah table perantara untuk menghubungkan event dan rfi.

Untuk mencari senarai url yang pernah digunakan dalam serangan yang berasal dari ip=34.98.6.134, Subqueries yang digunakan adalah seperti berikut:
Select url from rfi where rfi_id in
(Select rfi_id from event2rfi where event_id in
(select id from event where attacker="34.98.6.134")
)

Malangnya dari analisa yang dibuat menggunakan kata kunci explain, didapati mysql gagal menggunakan index yang terdapat dalam table event.(Walaupun index telah di buat untuk field rfi_id dalam table rfi).
explain select url from rfi where rfi_id in (SELECT rfi_id FROM event2rfi WHERE event_id IN ( SELECT id FROM event WHERE attacker = '34.98.6.134' ));
+----+--------------------+-----------+-----------------+---------------+---------+---------+------+-------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+--------------------+-----------+-----------------+---------------+---------+---------+------+-------+-------------+
| 1 | PRIMARY | rfi | ALL | NULL | NULL | NULL | NULL | 65696 | Using where |
| 2 | DEPENDENT SUBQUERY | event2rfi | index_subquery | rfi_id | rfi_id | 8 | func | 28 | Using where |
| 3 | DEPENDENT SUBQUERY | event | unique_subquery | PRIMARY | PRIMARY | 4 | func | 1 | Using where |
+----+--------------------+-----------+-----------------+---------------+---------+---------+------+-------+-------------+

Pada baris pertama, lajur possible_keys, mengandungi value NULL. Ini bermaksud mysql enjin tidak akan menggunakan sebarang index dan akan meyebabkan prestasi carian data menjunam. Ingin ditekankan sekali lagi bahawa table rfi mempunyai index pada field rfi_id. Namun mysql gagal mengenal pasti sekali gus menggunakan index tersebut.

Penyelesaian.
Kata pakcik google version 5.2 akan mengatasi masalah ini. Version yang kami gunakan adalah 5.1.37, version yang disertakan dalam distro ubuntu.
Untuk melajukan proses carian, kod tersebut diubah kepada 3 sql yang berasingan.

Sql pertama ialah mencari senarai event.id berdasarkan attackerIp.

Hasil yang didapati akan digunakan dalam sql ke-2. Iaitu mencari senarai event2rfi.rfi_id where event2rfi.event_id in (X,Y,Z……).

Kemudian senarai event2rfi.rfi_id pula akan digunakan dalam carian ke-3. Iaitu mencari senarai rfi.url where rfi.rfi_id in (X,Y,Z……)

Masalah selesai. Walaubagaimanapun agak menghairankan bug ini masih berlaku dalam mysql yg rata-rata nya dikatakan orang amat bagus.

Leave a Reply