ฉันควรใช้ดัชนีผสมเมื่อใด


133
  1. ฉันควรใช้ดัชนีผสมในฐานข้อมูลเมื่อใด
  2. การแบ่งประสิทธิภาพโดยใช้ดัชนีคอมโพสิต) คืออะไร?
  3. เหตุใดฉันจึงควรใช้ดัชนีผสม

ตัวอย่างเช่นฉันมีhomesตาราง:

CREATE TABLE IF NOT EXISTS `homes` (
  `home_id` int(10) unsigned NOT NULL auto_increment,
  `sqft` smallint(5) unsigned NOT NULL,
  `year_built` smallint(5) unsigned NOT NULL,
  `geolat` decimal(10,6) default NULL,
  `geolng` decimal(10,6) default NULL,
  PRIMARY KEY  (`home_id`),
  KEY `geolat` (`geolat`),
  KEY `geolng` (`geolng`),
) ENGINE=InnoDB  ;

มันสมเหตุสมผลหรือไม่ที่ฉันจะใช้ดัชนีผสมสำหรับทั้งสองgeolatและgeolngเช่นนั้น:

ฉันแทนที่:

  KEY `geolat` (`geolat`),
  KEY `geolng` (`geolng`),

ด้วย:

KEY `geolat_geolng` (`geolat`, `geolng`)

ถ้าเป็นเช่นนั้น:

  • ทำไม?
  • อัตราส่วนประสิทธิภาพโดยใช้ดัชนีคอมโพสิตคืออะไร)?

UPDATE:

เนื่องจากหลายคนระบุว่ามันขึ้นอยู่กับคำถามที่ฉันดำเนินการทั้งหมดด้านล่างนี้คือคำค้นหาที่ใช้บ่อยที่สุด:

SELECT * FROM homes
WHERE geolat BETWEEN ??? AND ???
AND geolng BETWEEN ??? AND ???

อัปเดต 2:

ด้วยสคีมาฐานข้อมูลต่อไปนี้:

CREATE TABLE IF NOT EXISTS `homes` (
  `home_id` int(10) unsigned NOT NULL auto_increment,
  `primary_photo_group_id` int(10) unsigned NOT NULL default '0',
  `customer_id` bigint(20) unsigned NOT NULL,
  `account_type_id` int(11) NOT NULL,
  `address` varchar(128) collate utf8_unicode_ci NOT NULL,
  `city` varchar(64) collate utf8_unicode_ci NOT NULL,
  `state` varchar(2) collate utf8_unicode_ci NOT NULL,
  `zip` mediumint(8) unsigned NOT NULL,
  `price` mediumint(8) unsigned NOT NULL,
  `sqft` smallint(5) unsigned NOT NULL,
  `year_built` smallint(5) unsigned NOT NULL,
  `num_of_beds` tinyint(3) unsigned NOT NULL,
  `num_of_baths` decimal(3,1) unsigned NOT NULL,
  `num_of_floors` tinyint(3) unsigned NOT NULL,
  `description` text collate utf8_unicode_ci,
  `geolat` decimal(10,6) default NULL,
  `geolng` decimal(10,6) default NULL,
  `display_status` tinyint(1) NOT NULL,
  `date_listed` timestamp NOT NULL default CURRENT_TIMESTAMP,
  `contact_email` varchar(100) collate utf8_unicode_ci NOT NULL,
  `contact_phone_number` varchar(15) collate utf8_unicode_ci NOT NULL,
  PRIMARY KEY  (`home_id`),
  KEY `customer_id` (`customer_id`),
  KEY `city` (`city`),
  KEY `num_of_beds` (`num_of_beds`),
  KEY `num_of_baths` (`num_of_baths`),
  KEY `geolat` (`geolat`),
  KEY `geolng` (`geolng`),
  KEY `account_type_id` (`account_type_id`),
  KEY `display_status` (`display_status`),
  KEY `sqft` (`sqft`),
  KEY `price` (`price`),
  KEY `primary_photo_group_id` (`primary_photo_group_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=8 ;

ใช้ SQL ต่อไปนี้:

EXPLAIN SELECT  homes.home_id,
                    address,
                    city,
                    state,
                    zip,
                    price,
                    sqft,
                    year_built,
                    account_type_id,
                    num_of_beds,
                    num_of_baths,
                    geolat,
                    geolng,
                    photo_id,
                    photo_url_dir
            FROM homes
            LEFT OUTER JOIN home_photos ON homes.home_id = home_photos.home_id
                AND homes.primary_photo_group_id = home_photos.home_photo_group_id
                AND home_photos.home_photo_type_id = 2
            WHERE homes.display_status = true
            AND homes.geolat BETWEEN -100 AND 100
            AND homes.geolng BETWEEN -100 AND 100

EXPLAIN ส่งคืน:

id  select_type  table        type  possible_keys                                    key                  key_len  ref     rows  Extra
----------------------------------------------------------------------------------------------------------
1   SIMPLE       homes        ref   geolat,geolng,display_status                     display_status       1        const   2     Using where
1  SIMPLE        home_photos  ref   home_id,home_photo_type_id,home_photo_group_id   home_photo_group_id  4        homes.primary_photo_group_id   4  

ฉันไม่ค่อยเข้าใจวิธีอ่านคำสั่ง EXPLAIN สิ่งนี้ดูดีหรือไม่ดี ตอนนี้ฉันไม่ได้ใช้ดัชนีผสมสำหรับ geolat และ geolng ฉันควรจะเป็น?

คำตอบ:


111

คุณควรใช้ดัชนีผสมเมื่อคุณใช้แบบสอบถามที่ได้รับประโยชน์จากมัน ดัชนีคอมโพสิตที่มีลักษณะดังนี้:

index( column_A, column_B, column_C )

จะเป็นประโยชน์ต่อแบบสอบถามที่ใช้ฟิลด์เหล่านั้นในการเข้าร่วมการกรองและบางครั้งการเลือก นอกจากนี้ยังจะเป็นประโยชน์ต่อการสืบค้นที่ใช้คอลัมน์ย่อยด้านซ้ายสุดของคอลัมน์ในคอมโพสิตนั้น ดังนั้นดัชนีข้างต้นจะตอบสนองการสืบค้นที่ต้องการ

index( column_A, column_B, column_C )
index( column_A, column_B )
index( column_A )

แต่จะไม่ (อย่างน้อยก็ไม่โดยตรงอาจช่วยได้บางส่วนหากไม่มีดัชนีที่ดีกว่า) ช่วยในการสืบค้นที่ต้องการ

index( column_A, column_C )

สังเกตว่า column_B หายไปอย่างไร

ในตัวอย่างเดิมของคุณดัชนีผสมสำหรับสองมิติส่วนใหญ่จะเป็นประโยชน์ต่อคำค้นหาที่ค้นหาทั้งสองมิติหรือมิติด้านซ้ายสุดด้วยตัวมันเอง แต่ไม่ใช่มิติด้านขวาสุดด้วยตัวมันเอง หากคุณกำลังค้นหาสองมิติเสมอดัชนีคอมโพสิตคือหนทางที่จะไปไม่สำคัญว่าอันไหนเป็นอันดับแรก (ส่วนใหญ่อาจเป็น)


1
มาร์คฉันได้อัปเดตโพสต์เดิมของฉันแล้ว (อัปเดต 2) นี่คือคำถามที่แท้จริงของฉัน สคีมาฐานข้อมูลจริงของฉัน และสิ่งที่คำสั่ง EXPLAIN ส่งกลับ ดังนั้นด้วยข้อมูลนี้ฉันควรใช้ดัชนีผสม ฉันยังไม่ชัดเจน ขอบคุณล่วงหน้า.
Teddy

ทำเครื่องหมายดัชนีผสมในคำตอบของคุณตรงตามดัชนี (column_C) หรือไม่
Boris D.Teoharov

ฉันไม่แน่ใจว่าฉันเข้าใจคำถามของคุณ แต่ถ้าคุณถามว่าดัชนี (A, B, C) จะช่วยคิวรีที่กรองคอลัมน์ C ได้หรือไม่คำตอบมักจะเป็นไม่ก็จะไม่ใช้ดัชนีในการกรอง อย่างไรก็ตามสามารถใช้ดัชนีเพื่อกำจัดการสแกนตารางได้หากคุณเลือกเฉพาะส่วนย่อยของ ABC ที่แตกต่างกัน แต่เกี่ยวข้องกัน แต่สำหรับการใช้ดัชนีโดยทั่วไปเพื่อเปิดใช้งานการกรองคำตอบคือไม่
Mark Canlas

1
-1 เพราะดัชนีคอมโพสิตจะไม่ได้WHERE geolat BETWEEN ??? AND ??? AND geolng BETWEEN ??? AND ???ความช่วยเหลือเกี่ยวกับ มันจะหยุดหลังจากฟิลด์แรก คำตอบจาก "คำถามล้น" อธิบายว่าทำไม
Rick James

1
@felwithe MySQL สามารถใช้ดัชนีได้เพียงหนึ่งดัชนีต่อแต่ละตารางในแบบสอบถาม (มีข้อยกเว้นเช่นการรวมดัชนี) ซึ่งหมายความว่าตารางในแบบสอบถามจะต้องใช้ดัชนีเดียวสำหรับคำสั่ง where-clause, table join, group-by และ order-by ทั้งหมด ดังนั้นดัชนีที่แยกจากกันในแต่ละคอลัมน์อาจไม่ได้ผลเสมอไป แต่ดัชนีผสมสามารถทำเวทมนตร์
AKHIL MATHEW

57

สมมติว่าคุณมีคำถามสามข้อต่อไปนี้:

แบบสอบถาม I:

SELECT * FROM homes WHERE `geolat`=42.9 AND `geolng`=36.4

แบบสอบถาม II:

SELECT * FROM homes WHERE `geolat`=42.9

แบบสอบถาม III:

SELECT * FROM homes WHERE `geolng`=36.4

หากคุณมีดัชนีแยกกันต่อคอลัมน์แบบสอบถามทั้งสามใช้ดัชนี ใน MySQL ถ้าคุณมีดัชนีคอมโพสิต ( geolat, geolng) เฉพาะแบบสอบถาม I และแบบสอบถาม II (ซึ่งใช้ส่วนแรกของดัชนีผสม) เท่านั้นที่ใช้ดัชนี ในกรณีนี้คิวรี III ต้องการการค้นหาแบบเต็มตาราง

ในส่วนดัชนีหลายคอลัมน์ของคู่มืออธิบายไว้อย่างชัดเจนว่าดัชนีหลายคอลัมน์ทำงานอย่างไรดังนั้นฉันจึงไม่ต้องการพิมพ์คู่มือซ้ำ

จากหน้าคู่มืออ้างอิง MySQL :

ดัชนีหลายคอลัมน์ได้รับการพิจารณาเป็นแถวเรียงที่มีค่าที่ถูกสร้างขึ้นโดยการเชื่อมโยงคุณค่าของคอลัมน์จัดทำดัชนี

หากคุณใช้ดัชนีแยกสำหรับคอลัมน์ geolat และ geolng คุณจะมีดัชนีที่แตกต่างกันสองดัชนีในตารางของคุณซึ่งคุณสามารถค้นหาได้โดยอิสระ

INDEX geolat
-----------
VALUE RRN
36.4  1
36.4  8
36.6  2
37.8  3
37.8  12
41.4  4

INDEX geolng
-----------
VALUE RRN
26.1  1
26.1  8
29.6  2
29.6  3
30.1  12
34.7  4

หากคุณใช้ดัชนีผสมคุณมีเพียงดัชนีเดียวสำหรับทั้งสองคอลัมน์:

INDEX (geolat, geolng)
-----------
VALUE      RRN
36.4,26.1  1
36.4,26.1  8
36.6,29.6  2
37.8,29.6  3
37.8,30.1  12
41.4,34.7  4

RRN คือหมายเลขบันทึกสัมพัทธ์ (เพื่อให้ง่ายขึ้นคุณสามารถพูดว่า ID) ดัชนีสองตัวแรกสร้างแยกกันและดัชนีที่สามเป็นแบบผสม ดังที่คุณเห็นคุณสามารถค้นหาตาม geolng บนคอมโพสิตเนื่องจากมีการจัดทำดัชนีโดย geolat อย่างไรก็ตามสามารถค้นหาโดย geolat หรือ "geolat AND geolng" (เนื่องจาก geolng เป็นดัชนีระดับที่สอง)

นอกจากนี้โปรดดูที่ส่วนคู่มือการใช้ดัชนี MySQL อย่างไร


1
อันที่จริงฉันไม่มีคำถามเหล่านั้นเลย ข้อความค้นหาของฉันแสดงอยู่ในโพสต์ต้นฉบับ คำถามของฉันคือการส่งคืนบ้านภายในตารางสี่เหลี่ยม ฉันรู้เกี่ยวกับอวกาศและฉันไม่ได้พยายามคำนวณระยะทาง ฉันแค่อยากรู้ว่าการใช้ดัชนีคอมโพสิตนั้นสมเหตุสมผลหรือไม่เมื่อฉันพยายามแสดงบ้านทั้งหมดภายในตารางภูมิศาสตร์เฉพาะ (เช่นพื้นที่ใกล้เคียง / เมือง / เขต)
Teddy

Eyazici ฉันได้อัปเดตโพสต์เดิมของฉันแล้ว (อัพเดท 2) นี่คือคำถามที่แท้จริงของฉัน สคีมาฐานข้อมูลจริงของฉัน และสิ่งที่คำสั่ง EXPLAIN ส่งกลับ ดังนั้นด้วยข้อมูลนี้ฉันควรใช้ดัชนีผสม ฉันยังไม่ชัดเจน ขอบคุณล่วงหน้า
Teddy

@ "ที่จริงฉันไม่มีคำถามเหล่านั้น". ที่จริงคุณมีฉันใช้ WHERE condition ง่ายๆในการอธิบายตรรกะพื้นฐาน เมื่อใช้เงื่อนไข (เช่น WHERE) บนคอลัมน์ MySQL จะพยายามใช้ดัชนีทุกครั้งที่ทำได้ "x ระหว่าง a AND b" คล้ายกับ "x> a และ x <b" คุณได้ใช้ทั้งคอลัมน์ geolng และ geolat ในแบบสอบถามแบบมีเงื่อนไข หากคุณใช้ดัชนีผสม "(geolat, geolng)" ของคุณ "AND geolng ระหว่าง ??? และ ???" เงื่อนไขไม่ได้รับประโยชน์จากดัชนี (สำหรับ MySQL) ดังนั้นคุณควรใช้ดัชนีแยกกันต่อคอลัมน์สำหรับสถานการณ์ของคุณ
Emre Yazici

ฉันไม่เข้าใจ. เหตุใดฉันจึงควรใช้ดัชนีแยกกันสำหรับ geolat และ geolng เมื่อฉันมักจะดำเนินการค้นหาที่มีทั้งสองคอลัมน์
Teddy

1
ไม่เมื่อพบ "ช่วง" (เช่นเดียวกับBETWEEN) จะไม่มีการพิจารณาฟิลด์ใด ๆ ของดัชนีอีกต่อไป! ดังนั้นดัชนีคอมโพสิตจึงไม่ดีกว่า
Rick James

19

อาจมีความเข้าใจผิดเกี่ยวกับสิ่งที่ดัชนีคอมโพสิตทำ หลายคนคิดว่าดัชนีคอมโพสิตสามารถนำมาใช้เพื่อเพิ่มประสิทธิภาพการค้นหาตราบใดที่whereข้อครอบคลุมคอลัมน์การจัดทำดัชนีในกรณีของคุณและgeolat geolngมาเจาะลึกกัน:

ฉันเชื่อว่าข้อมูลของคุณเกี่ยวกับพิกัดของบ้านจะเป็นทศนิยมแบบสุ่มดังนี้:

home_id  geolat  geolng
   1    20.1243  50.4521
   2    22.6456  51.1564
   3    13.5464  45.4562
   4    55.5642 166.5756
   5    24.2624  27.4564
   6    62.1564  24.2542
...

ตั้งแต่geolatและgeolngคุณค่าแทบจะไม่ซ้ำรอย ดัชนีคอมโพสิตเปิดอยู่geolatและgeolngจะมีลักษณะดังนี้:

index_id  geolat  geolng
   1     20.1243  50.4521
   2     20.1244  61.1564
   3     20.1251  55.4562
   4     20.1293  66.5756
   5     20.1302  57.4564
   6     20.1311  54.2542
...

ดังนั้นคอลัมน์ที่สองของดัชนีคอมโพสิตจึงไร้ประโยชน์โดยทั่วไป! ความเร็วของการสืบค้นของคุณด้วยดัชนีคอมโพสิตอาจจะใกล้เคียงกับดัชนีในgeolatคอลัมน์เท่านั้น

ดังที่ Will กล่าวไว้ MySQL ให้การสนับสนุนส่วนขยายเชิงพื้นที่ จุดเชิงพื้นที่จะถูกเก็บไว้ในคอลัมน์เดียวแทนที่จะเป็นสองlat lngคอลัมน์ที่แยกจากกัน สามารถใช้ดัชนีเชิงพื้นที่กับคอลัมน์ดังกล่าวได้ อย่างไรก็ตามประสิทธิภาพอาจเกินจริงตามประสบการณ์ส่วนตัวของฉัน มันอาจเป็นไปได้ว่าดัชนีเชิงพื้นที่ไม่สามารถแก้ปัญหาที่เกิดขึ้นสองมิติ แต่เพียงความเร็วในการค้นหาโดยใช้R-ต้นไม้ที่มีการแยกกำลังสอง

ข้อเสียคือจุดเชิงพื้นที่ใช้หน่วยความจำมากกว่าเนื่องจากใช้ตัวเลขความแม่นยำสองเท่าแปดไบต์ในการจัดเก็บพิกัด แก้ไขฉันถ้าฉันผิด


5

ดัชนีคอมโพสิตมีประสิทธิภาพมากเนื่องจาก:

  • บังคับใช้ความสมบูรณ์ของโครงสร้าง
  • เปิดใช้งานการเรียงลำดับบน ID FILTERED

บังคับใช้ความซื่อสัตย์ของโครงสร้าง

ดัชนีคอมโพสิตไม่ได้เป็นเพียงดัชนีประเภทอื่น พวกเขาสามารถจัดเตรียมโครงสร้างที่จำเป็นให้กับตารางโดยการบังคับใช้ความสมบูรณ์เป็นคีย์หลัก

Innodb ของ Mysql สนับสนุนการทำคลัสเตอร์และตัวอย่างต่อไปนี้แสดงให้เห็นว่าเหตุใดจึงจำเป็นต้องมีดัชนีคอมโพสิต

ในการสร้างตารางของเพื่อน (เช่นสำหรับเครือข่ายสังคม) เราต้องมี 2 คอลัมน์: user_id, friend_id.

โครงสร้างตาราง

user_id (medium_int)
friend_id (medium_int)

Primary Key -> (user_id, friend_id)

โดยหลักการแล้วคีย์หลัก (PK) จะไม่ซ้ำกันและด้วยการสร้าง PK แบบผสม Innodb จะตรวจสอบโดยอัตโนมัติว่าไม่มีรายการที่ซ้ำกันuser_id, friend_idอยู่เมื่อมีการเพิ่มระเบียนใหม่ นี่เป็นลักษณะการทำงานที่คาดไว้เนื่องจากไม่มีผู้ใช้ควรมีมากกว่า 1 ระเบียน (ลิงก์ความสัมพันธ์) ด้วยfriend_id = 2เช่น

หากไม่มี PK แบบผสมเราสามารถสร้างสคีมานี้โดยใช้รหัสตัวแทน:

user_friend_id
user_id
friend_id

Primary Key -> (user_friend_id)

ตอนนี้เมื่อใดก็ตามที่มีการเพิ่มระเบียนใหม่เราจะต้องตรวจสอบว่าไม่มีบันทึกก่อนหน้านี้ที่มีชุดค่าผสมuser_id, friend_idอยู่

ด้วยเหตุนี้ดัชนีคอมโพสิตจึงสามารถบังคับใช้ความสมบูรณ์ของโครงสร้างได้

เปิดใช้งานการจัดเรียงบน ID ที่กรอง

เป็นเรื่องปกติมากที่จะจัดเรียงชุดของระเบียนตามเวลาของโพสต์ (การประทับเวลาหรือวันที่และเวลา) โดยปกติแล้วจะหมายถึงการโพสต์บนรหัสที่กำหนด นี่คือตัวอย่าง

ตาราง User_Wall_Posts (คิดว่าถ้าโพสต์บนผนังของ Facebook)

user_id (medium_int)
timestamp (timestamp)
author_id (medium_int)
comment_post (text)

Primary Key -> (user_id, timestamp, author_id)

เราต้องการสอบถามและค้นหาโพสต์ทั้งหมดuser_id = 10และจัดเรียงโพสต์ความคิดเห็นตามtimestamp(วันที่)

SQL QUERY

SELECT * FROM User_Wall_Posts WHERE user_id = 10 ORDER BY timestamp DES

PK แบบผสมช่วยให้ Mysql สามารถกรองและจัดเรียงผลลัพธ์โดยใช้ดัชนี Mysql จะไม่ต้องใช้ไฟล์ชั่วคราวหรือ filesort เพื่อดึงผลลัพธ์ หากไม่มีคีย์ผสมจะเป็นไปไม่ได้และจะทำให้เกิดการสืบค้นที่ไม่มีประสิทธิภาพ

ด้วยเหตุนี้คีย์คอมโพสิตจึงมีประสิทธิภาพมากและเหมาะกับปัญหาง่าย ๆ ของ "ฉันต้องการค้นหาcolumn_a, column_bดังนั้นฉันจะใช้คีย์ผสมสำหรับสคีมาฐานข้อมูลปัจจุบันของฉันฉันมีคีย์คอมโพสิตเพียงคีย์เดียวเท่านั้นอย่ามองข้าม การใช้คีย์คอมโพสิต!


5

ดัชนีคอมโพสิตมีประโยชน์สำหรับ

  • 0 หรือมากกว่า "=" อนุประโยคบวก
  • มากที่สุดหนึ่งช่วงประโยค

ดัชนีผสมไม่สามารถรองรับสองช่วง ผมหารือต่อไปนี้ฉันตำราดัชนี

ค้นหาที่ใกล้ที่สุด - หากคำถามเกี่ยวกับการเพิ่มประสิทธิภาพจริงๆ

WHERE geolat BETWEEN ??? AND ???
  AND geolng BETWEEN ??? AND ???

แล้วไม่มีดัชนีจริงๆสามารถจัดการทั้งมิติ

แต่เราต้อง 'คิดนอกกรอบ' แทน หากมิติหนึ่งถูกนำไปใช้ผ่านการแบ่งพาร์ติชันและอีกมิติหนึ่งถูกนำไปใช้โดยการเลือกอย่างระมัดระวังมิติPRIMARY KEYหนึ่งจะได้รับประสิทธิภาพที่ดีขึ้นอย่างมากสำหรับตารางการค้นหา lat / lng ขนาดใหญ่มาก บล็อก latlngของฉันจะกล่าวถึงรายละเอียดเกี่ยวกับวิธีใช้ "ค้นหาที่ใกล้ที่สุด" ในโลก รวมถึงรหัส

PARTITIONsมีลายเส้นของช่วงรุ้ง โดยPRIMARY KEYเจตนาเริ่มต้นด้วยลองจิจูดเพื่อให้แถวที่มีประโยชน์น่าจะอยู่ในบล็อกเดียวกัน กิจวัตรที่จัดเก็บไว้จะจัดระเบียบรหัสที่ยุ่งเหยิงสำหรับการทำorder by... limit...และเพื่อเพิ่ม 'สี่เหลี่ยมจัตุรัส' รอบ ๆ เป้าหมายจนกว่าคุณจะมีร้านกาแฟเพียงพอ (หรืออะไรก็ตาม) นอกจากนี้ยังดูแลการคำนวณแบบวงกลมใหญ่และการจัดการดาต้าไลน์และเสา

มากกว่า

ฉันเขียนบล็อกอื่นแล้ว มันเปรียบเทียบ 5 วิธีในการค้นหา lat / lng: http://mysql.rjweb.org/doc.php/latlng#representation_choices (อ้างอิงลิงค์ที่ให้ไว้ข้างต้นเป็นหนึ่งใน 5) อีกวิธีหนึ่งคือ และชี้ให้เห็นว่าเหมาะสมที่สุดสำหรับบางกรณี :

INDEX(geolat, geolng),
INDEX(geolng, geolat)

นั่นคือการมีทั้งสองคอลัมน์ในสองดัชนีและไม่มีดัชนีคอลัมน์เดียวใน geolat และ geolng เป็นสิ่งสำคัญ


1

ไม่มีขาวดำขนาดเดียวเหมาะกับทุกคำตอบ

คุณควรใช้ดัชนีผสมเมื่อภาระงานแบบสอบถามของคุณจะได้รับประโยชน์จากหนึ่ง

คุณต้องกำหนดโปรไฟล์ภาระงานการสืบค้นของคุณเพื่อพิจารณาสิ่งนี้

ดัชนีผสมเข้ามามีบทบาทเมื่อสามารถตอบคำถามจากดัชนีนั้นได้ทั้งหมด

อัปเดต (เพื่อตอบสนองต่อการแก้ไขคำถามที่โพสต์): หากคุณกำลังเลือก * จากตารางอาจใช้ดัชนีผสมอาจไม่ได้ คุณจะต้องเรียกใช้EXPLAIN PLANเพื่อความแน่ใจ


การใช้ดัชนีคอมโพสิตสำหรับข้อมูลตำแหน่งทางภูมิศาสตร์ (ละติจูดและลองจิจูด) เหมาะสมหรือไม่
Teddy

1
ขึ้นอยู่กับว่ามีการสอบถามอะไรกับตารางนั้น
Mitch Wheat

ฉันได้อัปเดตโพสต์ต้นฉบับของฉันเพื่อรวมข้อความค้นหาที่ใช้บ่อยที่สุด ดูด้านบน.
Teddy

1

ในการค้นหาแบบเว้นวรรคคุณต้องมีไฟล์ อัลกอริทึมR-Treeซึ่งช่วยให้ค้นหาพื้นที่ทางภูมิศาสตร์ได้อย่างรวดเร็ว สิ่งที่คุณต้องการสำหรับงานนี้

ฐานข้อมูลบางแห่งมีดัชนีเว้นวรรคในตัวการค้นหาโดย Google อย่างรวดเร็วแสดงให้เห็นว่า MySQL 5 มีอยู่ (ซึ่งเมื่อดู SQL ของคุณฉันเดาว่าคุณกำลังใช้ MySQL)


1

ดัชนีคอมโพสิตจะมีประโยชน์เมื่อคุณต้องการเพิ่มประสิทธิภาพgroup byประโยค (ตรวจสอบบทความนี้http://dev.mysql.com/doc/refman/5.0/en/group-by-optimization.html ) กรุณาให้ความสนใจ:

เงื่อนไขเบื้องต้นที่สำคัญที่สุดในการใช้ดัชนีสำหรับ GROUP BY คือแอตทริบิวต์การอ้างอิง GROUP BY คอลัมน์ทั้งหมดจากดัชนีเดียวกันและดัชนีจะจัดเก็บคีย์ตามลำดับ (ตัวอย่างเช่นนี่คือดัชนี BTREE ไม่ใช่ดัชนี HASH)


GROUP BYไม่ได้กล่าวถึง
Rick James

ไม่ได้กล่าวถึงที่ไหน :) มีการกล่าวถึงอย่างชัดเจนในบทความที่ฉันอ้างถึง และคำตอบสำหรับคำถามที่ถูกถาม: ฉันควรใช้ดัชนีผสมในฐานข้อมูลเมื่อใด การแบ่งประสิทธิภาพโดยใช้ดัชนีคอมโพสิต) คืออะไร? เหตุใดฉันจึงควรใช้ดัชนีผสม
Alexander

การแก้ไข: GROUP BY OP ไม่ได้กล่าวถึง
Rick James

แน่นอนว่านั่นคือคำตอบ - หนึ่งในกรณีที่เราจะใช้ดัชนีผสมในฐานข้อมูล
Alexander

0

ฉันอยู่กับ @Mitch ขึ้นอยู่กับคำถามของคุณทั้งหมด โชคดีที่คุณสามารถสร้างและวางดัชนีได้ตลอดเวลาและคุณสามารถใส่คำหลัก EXPLAIN ไว้ข้างหน้าข้อความค้นหาของคุณเพื่อดูว่าตัววิเคราะห์การสืบค้นใช้ดัชนีหรือไม่

หากคุณกำลังมองหาคู่ lat / long ที่แน่นอนดัชนีนี้น่าจะสมเหตุสมผล แต่คุณอาจกำลังมองหาบ้านที่อยู่ในระยะทางที่กำหนดของสถานที่หนึ่งดังนั้นคำค้นหาของคุณจะมีลักษณะดังนี้ (ดูแหล่งที่มา ):

select *, sqrt(  pow(h2.geolat - h1.geolat,  2) 
               + pow(h2.geolng - h1.geolng, 2) ) as distance
from homes h1, homes h2
where h1.home_id = 12345 and h2.home_id != h1.home_id
order by distance

และดัชนีมีแนวโน้มที่จะไม่เป็นประโยชน์เลย สำหรับการค้นหาเชิงพื้นที่ที่คุณต้องการอะไรเช่นนี้

อัปเดต: ด้วยคำถามนี้:

SELECT * FROM homes
WHERE geolat BETWEEN ??? AND ???
AND geolng BETWEEN ??? AND ???

ตัววิเคราะห์แบบสอบถามสามารถใช้ดัชนีบน geolat เพียงอย่างเดียวหรือดัชนีบน geolng เพียงอย่างเดียวหรืออาจเป็นทั้งดัชนี ฉันไม่คิดว่ามันจะใช้ดัชนีผสม แต่เป็นเรื่องง่ายที่จะลองใช้การเรียงสับเปลี่ยนเหล่านี้ในชุดข้อมูลจริงจากนั้น (ก) ดูว่า EXPLAIN บอกอะไรคุณและ (b) วัดเวลาที่แบบสอบถามใช้จริงๆ


ฉันแค่อยากจะกลับบ้านภายในตารางสี่เหลี่ยม ฉันรู้เกี่ยวกับอวกาศดังนั้นฉันไม่ได้พยายามคำนวณระยะทาง ฉันแค่ต้องการกลับบ้านภายในตารางสี่เหลี่ยมและต้องการให้ดำเนินการอย่างรวดเร็ว ดังนั้นฉันต้องการให้แน่ใจว่าฉันตั้งค่าดัชนีอย่างถูกต้อง ที่ช่วย?
Teddy
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.