Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> MySQL

เลือกหลายแถวใน MySQL ได้อย่างมีประสิทธิภาพด้วย Index และ IN()

Query หลายแถวได้เร็วด้วย Index + IN()

การใช้ WHERE id IN (val1, val2, ...) ร่วมกับ Index บนคอลัมน์ Id จะทำให้ MySQL ใช้ Index Lookup (ref/range) แทน Full Table Scan

สร้างตาราง พร้อม Primary Key (Index อัตโนมัติ)

mysql> CREATE TABLE DemoTable1501 (
    -> Id INT NOT NULL PRIMARY KEY,
    -> URL TEXT
    -> );
Query OK, 0 rows affected (0.62 sec)

-- สร้าง Index เพิ่ม (Redundant เพราะ PK มี Index แล้ว แต่เป็นตัวอย่าง)
mysql> CREATE INDEX id_index ON DemoTable1501(Id);
Query OK, 0 rows affected (0.23 sec)

เพิ่มข้อมูล

mysql> INSERT INTO DemoTable1501 VALUES
    -> (101, 'www.facebook.com'),
    -> (110, 'www.google.com'),
    -> (220, 'www.gmail.com'),
    -> (350, 'www.youtube.com');
Query OK, 4 rows affected

คำสั่ง: เลือก Id 101, 220, 350

mysql> SELECT * FROM DemoTable1501 WHERE Id IN (101, 220, 350);

ผลลัพธ์

+-----+------------------+
| Id  | URL              |
+-----+------------------+
| 101 | www.facebook.com |
| 220 | www.gmail.com    |
| 350 | www.youtube.com  |
+-----+------------------+

พิสูจน์ด้วย Handler Status: Handler_read_key = 3 (ใช่ Index 3 ครั้ง)

mysql> SHOW STATUS LIKE 'Handler_%';
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| Handler_read_key           | 3     |  <-- 3 Index Lookups
| Handler_read_rnd_next      | 0     |  <-- ไม่มี Full Table Scan
... (อื่นๆ) ...
+----------------------------+-------+

คำอธิบาย Handler Status

Best Practices สำหรับ IN()

  • ค่าภายใน IN() ควรเป็น Constant/Literal (ไม่ใช่ Subquery ที่ Complex)
  • จำนวนค่าใน IN() ไม่ควรมากเกินไป (< 1000 ค่า แนะนำใช้ Temporary Table / JOIN แทน)
  • คอลัมน์ใน WHERE ต้องมี Index
  • ใช้ EXPLAIN ตรวจสอบว่า type = 'range' หรือ 'ref'

ตัวอย่าง EXPLAIN

mysql> EXPLAIN SELECT * FROM DemoTable1501 WHERE Id IN (101, 220, 350);
+----+-------------+---------------+------------+-------+---------------+----------+---------+------+------+----------+-------------+
| id | select_type | table         | partitions | type  | possible_keys | key      | key_len | ref  | rows | filtered | Extra       |
+----+-------------+---------------+------------+-------+---------------+----------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | DemoTable1501 | NULL       | range | PRIMARY,id_index | PRIMARY | 4       | NULL |    3 |   100.00 | Using where |
+----+-------------+---------------+------------+-------+---------------+----------+---------+------+------+----------+-------------+
Variableความหมายค่าที่ดี
Handler_read_keyจำนวนครั้งที่อ่านผ่าน Indexมาก (เท่ากับจำนวนแถวที่ดึง)
Handler_read_rnd_nextจำนวนครั้งที่อ่านแถวถัดไปแบบ Sequential (Full Scan)0 หรือน้อยมาก
Handler_read_firstอ่านแถวแรกของ Index (Full Index Scan)น้อย