Khi nào tôi nên sử dụng một chỉ số tổng hợp?


133
  1. Khi nào tôi nên sử dụng một chỉ mục tổng hợp trong cơ sở dữ liệu?
  2. Sự phân nhánh hiệu suất bằng cách sử dụng một chỉ số tổng hợp) là gì?
  3. Tại sao tôi nên sử dụng chỉ số tổng hợp?

Ví dụ: tôi có một homesbảng:

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  ;

Liệu nó có ý nghĩa đối với tôi để sử dụng một chỉ số tổng hợp cho cả hai geolatgeolng, như vậy:

Tôi thay thế:

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

với:

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

Nếu vậy:

  • Tại sao?
  • Sự phân nhánh hiệu suất bằng cách sử dụng một chỉ số tổng hợp) là gì?

CẬP NHẬT:

Vì nhiều người đã tuyên bố nó hoàn toàn phụ thuộc vào các truy vấn tôi thực hiện, dưới đây là truy vấn phổ biến nhất được thực hiện:

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

CẬP NHẬT 2:

Với lược đồ cơ sở dữ liệu sau:

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 ;

Sử dụng SQL sau:

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

GIẢI THÍCH trả về:

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  

Tôi hoàn toàn không hiểu cách đọc lệnh EXPLAIN. Điều này có vẻ tốt hay xấu. Ngay bây giờ, tôi KHÔNG sử dụng chỉ mục tổng hợp cho geolat và geolng. Tôi có nên

Câu trả lời:


111

Bạn nên sử dụng một chỉ mục tổng hợp khi bạn đang sử dụng các truy vấn có lợi từ nó. Một chỉ số tổng hợp trông như thế này:

index( column_A, column_B, column_C )

sẽ có lợi cho một truy vấn sử dụng các trường đó để tham gia, lọc và đôi khi chọn. Nó cũng sẽ có lợi cho các truy vấn sử dụng các tập hợp con của hầu hết các cột trong tổ hợp đó. Vì vậy, chỉ số trên cũng sẽ đáp ứng các truy vấn cần

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

Nhưng nó sẽ không (ít nhất là không trực tiếp, có thể nó có thể giúp một phần nếu không có chỉ số tốt hơn) giúp cho các truy vấn cần

index( column_A, column_C )

Lưu ý cách cột_B bị thiếu.

Trong ví dụ ban đầu của bạn, một chỉ mục tổng hợp cho hai thứ nguyên sẽ chủ yếu mang lại lợi ích cho các truy vấn truy vấn trên cả hai chiều hoặc theo chiều bên trái, nhưng không phải là thứ nguyên ngoài cùng bên phải. Nếu bạn luôn truy vấn hai chiều, một chỉ số tổng hợp là hướng đi, thì thực sự không phải là vấn đề đầu tiên (rất có thể).


1
Đánh dấu, tôi đã cập nhật bài viết gốc của mình (cập nhật 2). Đây là truy vấn thực tế của tôi. Lược đồ db thực tế của tôi. Và những gì lệnh EXPLAIN trả về. Vì vậy, với thông tin này - tôi có nên sử dụng chỉ mục tổng hợp. Tôi vẫn chưa rõ ràng. Cảm ơn trước.
Teddy

Đánh dấu, chỉ mục tổng hợp trong câu trả lời của bạn có thỏa mãn chỉ số (cột_C) không?
Boris D. Teoharov

Tôi không chắc là tôi hiểu câu hỏi của bạn. Nhưng, nếu bạn hỏi liệu chỉ mục (A, B, C) có giúp truy vấn lọc trên cột C hay không, câu trả lời thường là không, nó sẽ không sử dụng chỉ mục để lọc. Tuy nhiên, nó có thể sử dụng chỉ mục để loại bỏ quét bảng nếu bạn chỉ chọn trên một tập hợp con của ABC. Vì vậy, đó là khác nhau, nhưng có liên quan. Nhưng đối với việc sử dụng các chỉ mục thông thường để cho phép lọc, câu trả lời là không.
Mark Canlas

1
-1 vì một chỉ số tổng hợp không giúp được gì WHERE geolat BETWEEN ??? AND ??? AND geolng BETWEEN ??? AND ???. Nó sẽ dừng lại sau trường đầu tiên. Câu trả lời từ "Câu hỏi tràn" giải thích tại sao.
Rick James

1
@felwithe MySQL chỉ có thể sử dụng một chỉ mục cho mỗi bảng trong một truy vấn (Miễn trừ là có. Ví dụ: Hợp nhất các chỉ mục). Điều này lý tưởng có nghĩa là một bảng trong một truy vấn, phải sử dụng một chỉ mục duy nhất cho tất cả mệnh đề where, tham gia bảng, theo nhóm và theo thứ tự. Vì vậy, một chỉ mục riêng biệt trên mỗi cột có thể không hoạt động luôn nhưng một chỉ mục tổng hợp có thể làm nên điều kỳ diệu.
AKHIL MATHEW

56

Hãy tưởng tượng bạn có ba truy vấn sau:

Truy vấn I:

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

Truy vấn II:

SELECT * FROM homes WHERE `geolat`=42.9

Truy vấn III:

SELECT * FROM homes WHERE `geolng`=36.4

Nếu bạn có chỉ mục riêng biệt trên mỗi cột, cả ba truy vấn đều sử dụng chỉ mục. Trong MySQL, nếu bạn có chỉ mục tổng hợp ( geolat, geolng), chỉ truy vấn I và truy vấn II (đang sử dụng phần đầu tiên của chỉ mục tổng hợp) sử dụng các chỉ mục. Trong trường hợp này, truy vấn III yêu cầu tìm kiếm bảng đầy đủ.

Trên phần Chỉ mục nhiều cột của hướng dẫn sử dụng, nó được giải thích rõ ràng về cách hoạt động của nhiều chỉ mục cột, vì vậy tôi không muốn nhập lại thủ công.

Từ trang Hướng dẫn tham khảo MySQL :

Một chỉ mục nhiều cột có thể được coi là một mảng được sắp xếp chứa các giá trị được tạo bằng cách ghép các giá trị của các cột được lập chỉ mục .

Nếu bạn sử dụng chỉ mục riêng biệt cho các cột geolat và geolng, bạn có hai chỉ mục khác nhau trong bảng mà bạn có thể tìm kiếm độc lập.

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

Nếu bạn sử dụng chỉ mục tổng hợp, bạn chỉ có một chỉ mục cho cả hai cột:

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 là số bản ghi tương đối (để đơn giản hóa, bạn có thể nói ID). Hai chỉ số đầu tiên được tạo riêng biệt và chỉ mục thứ ba là tổng hợp. Như bạn có thể thấy, bạn có thể tìm kiếm dựa trên geolng trên hỗn hợp vì nó được lập chỉ mục bởi geolat, tuy nhiên có thể tìm kiếm theo geolat hoặc "geolat AND geolng" (vì geolng là chỉ mục cấp thứ hai).

Ngoài ra, hãy xem phần hướng dẫn sử dụng MySQL sử dụng chỉ mục.


1
Trên thực tế, tôi không có bất kỳ truy vấn nào. Truy vấn của tôi được liệt kê trong bài viết gốc. Truy vấn của tôi là trả lại nhà trong một lưới vuông. Tôi biết về không gian và tôi không cố tính khoảng cách. Tôi chỉ đơn giản muốn biết liệu sử dụng chỉ mục tổng hợp có hợp lý hay không khi tôi đang cố gắng hiển thị tất cả các ngôi nhà trong một lưới địa lý cụ thể (ví dụ: khu phố / thành phố / quận)
Teddy

Eyazici, tôi đã cập nhật bài viết gốc của mình (cập nhật 2). Đây là truy vấn thực tế của tôi. Lược đồ db thực tế của tôi. Và những gì lệnh EXPLAIN trả về. Vì vậy, với thông tin này - tôi có nên sử dụng chỉ mục tổng hợp. Tôi vẫn chưa rõ ràng. Cảm ơn trước
Teddy

@ "Trên thực tế, tôi không có bất kỳ truy vấn nào trong số đó." Trên thực tế bạn có, tôi đã sử dụng điều kiện WHERE đơn giản để khám phá logic cơ sở. Khi sử dụng một điều kiện (tức là WHERE) trên một cột, MySQL cố gắng sử dụng các chỉ mục bất cứ khi nào có thể. "x GIỮA a VÀ b" tương tự như "x> a AND x <b". Bạn đã sử dụng cả hai cột geolng và geolat trong điều kiện truy vấn của bạn. Nếu bạn sử dụng chỉ mục tổng hợp "(geolat, geolng)" của bạn "VÀ geolng GIỮA ??? VÀ ???" có điều kiện không đạt được lợi thế của chỉ mục (điều này là dành cho MySQL). Vì vậy, bạn nên sử dụng chỉ mục riêng cho mỗi cột cho kịch bản của bạn.
Emre Yazici

Tôi không hiểu Tại sao tôi nên sử dụng các chỉ mục riêng cho geolat và geolng khi tôi LUÔN LUÔN thực hiện một truy vấn bao gồm cả hai cột
Teddy

1
Không. Khi gặp "phạm vi" (như với BETWEEN), không có trường nào nữa của chỉ mục được xem xét! Vì vậy, chỉ số tổng hợp là không tốt hơn.
Rick James

19

Có thể có một quan niệm sai lầm về những gì chỉ số tổng hợp làm. Nhiều người nghĩ rằng chỉ mục tổng hợp có thể được sử dụng để tối ưu hóa truy vấn tìm kiếm miễn là wheremệnh đề bao gồm các cột được lập chỉ mục, trong trường hợp của bạn geolatgeolng. Hãy đi sâu hơn:

Tôi tin rằng dữ liệu của bạn về tọa độ của các ngôi nhà sẽ là số thập phân ngẫu nhiên như sau:

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
...

geolatgeolnggiá trị hầu như không lặp lại. Một chỉ số tổng hợp trên geolatgeolngsẽ trông giống như thế này:

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
...

Do đó, cột thứ hai của chỉ số tổng hợp về cơ bản là vô dụng ! Tốc độ truy vấn của bạn với một chỉ mục tổng hợp có thể sẽ tương tự như một chỉ mục trên geolatcột.

Như Will đã đề cập, MySQL cung cấp hỗ trợ mở rộng không gian . Một điểm không gian được lưu trữ trong một cột thay vì hai lat lngcột riêng biệt . Chỉ số không gian có thể được áp dụng cho một cột như vậy. Tuy nhiên, hiệu quả có thể được đánh giá cao dựa trên kinh nghiệm cá nhân của tôi. Có thể là chỉ số không gian không giải quyết được vấn đề hai chiều mà chỉ tăng tốc tìm kiếm bằng cách sử dụng R-Plants với phân chia bậc hai .

Sự đánh đổi là một điểm không gian tiêu tốn nhiều bộ nhớ hơn khi nó sử dụng các số có độ chính xác kép tám byte để lưu trữ tọa độ. Đúng nếu tôi đã sai lầm.


5

Các chỉ số tổng hợp rất mạnh vì chúng:

  • Thực thi toàn vẹn cấu trúc
  • Cho phép sắp xếp trên id LỌC

TÍCH HỢP CẤU TRÚC THỰC HIỆN

Chỉ số tổng hợp không chỉ là một loại chỉ mục khác; họ có thể cung cấp cấu trúc CẦN THIẾT cho một bảng bằng cách thực thi tính toàn vẹn làm Khóa chính.

Innodb của Mysql hỗ trợ phân cụm và ví dụ sau minh họa tại sao một chỉ số tổng hợp có thể cần thiết.

Để tạo bảng của bạn bè (ví dụ: đối với mạng xã hội), chúng ta cần 2 cột : user_id, friend_id.

Bảng phân tầng

user_id (medium_int)
friend_id (medium_int)

Primary Key -> (user_id, friend_id)

Theo nguyên tắc, Khóa chính (PK) là duy nhất và bằng cách tạo PK tổng hợp, Innodb sẽ tự động kiểm tra xem không có bản sao user_id, friend_idnào tồn tại khi bản ghi mới được thêm vào. Đây là hành vi được mong đợi vì chẳng có người dùng nào nên có nhiều hơn 1 bản ghi (liên kết mối quan hệ) friend_id = 2chẳng hạn.

Nếu không có PK tổng hợp, chúng ta có thể tạo lược đồ này bằng khóa thay thế:

user_friend_id
user_id
friend_id

Primary Key -> (user_friend_id)

Bây giờ, bất cứ khi nào một bản ghi mới được thêm vào, chúng tôi sẽ phải kiểm tra xem bản ghi trước đó với sự kết hợp user_id, friend_idchưa tồn tại.

Như vậy, một chỉ số tổng hợp có thể thực thi toàn vẹn cấu trúc.

SABLEING SINGING TRÊN ID LỌC

Việc sắp xếp một tập hợp các bản ghi theo thời gian của bài đăng (dấu thời gian hoặc thời gian) là rất phổ biến. Thông thường, điều này có nghĩa là đăng trên một id nhất định. Đây là một ví dụ

Bảng User_Wall_Posts (suy nghĩ nếu bài đăng trên tường của Facebook)

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

Primary Key -> (user_id, timestamp, author_id)

Chúng tôi muốn truy vấn và tìm tất cả các bài đăng user_id = 10và sắp xếp các bài đăng bình luận theo timestamp(ngày).

SỐ LƯỢNG SQL

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

PK tổng hợp cho phép Mysql lọc và sắp xếp kết quả bằng cách sử dụng chỉ mục; Mysql sẽ không phải sử dụng tệp tạm thời hoặc tệp tin để lấy kết quả. Nếu không có khóa tổng hợp, điều này sẽ không thể thực hiện được và sẽ gây ra một truy vấn rất kém hiệu quả.

Như vậy, các khóa tổng hợp rất mạnh và phù hợp hơn vấn đề đơn giản là "Tôi muốn tìm kiếm column_a, column_bvì vậy tôi sẽ sử dụng các khóa tổng hợp. Đối với lược đồ cơ sở dữ liệu hiện tại của tôi, tôi có nhiều khóa tổng hợp như các khóa đơn. sử dụng khóa tổng hợp!


5

Chỉ số tổng hợp rất hữu ích cho

  • 0 hoặc nhiều mệnh đề "=", cộng
  • nhiều nhất là một mệnh đề phạm vi.

Một chỉ số tổng hợp không thể xử lý hai phạm vi. Tôi thảo luận thêm về điều này trong cuốn sách nấu ăn chỉ số của tôi .

Tìm gần nhất - Nếu câu hỏi thực sự là về tối ưu hóa

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

sau đó không có chỉ số thực sự có thể xử lý cả hai chiều.

Thay vào đó, người ta phải 'nghĩ ra khỏi hộp'. Nếu một thứ nguyên được triển khai thông qua phân vùng và thứ nguyên khác được thực hiện bằng cách chọn cẩn thận PRIMARY KEY, một thứ có thể có hiệu quả tốt hơn đáng kể cho các bảng tra cứu lat / lng rất lớn. Blog latlng của tôi đi sâu vào chi tiết về cách triển khai "tìm gần nhất" trên toàn cầu. Nó bao gồm mã.

Các PARTITIONssọc của phạm vi vĩ độ. Việc PRIMARY KEYcố tình bắt đầu với kinh độ để các hàng hữu ích có thể nằm trong cùng một khối. Một thói quen được lưu trữ sẽ sắp xếp mã lộn xộn để thực hiện order by... limit...và phát triển 'hình vuông' xung quanh mục tiêu cho đến khi bạn có đủ cửa hàng cà phê (hoặc bất cứ điều gì). Nó cũng quan tâm đến các tính toán vòng tròn lớn và xử lý dòng dữ liệu và các cực.

Hơn

Tôi đã viết một blog khác; nó so sánh 5 cách thực hiện tìm kiếm lat / lng: http://mysql.rjweb.org/doc.php/latlng#interesentation_choices (Nó tham chiếu liên kết được đưa ra ở trên là một trong 5.) Một trong những cách khác là đây, và nó chỉ ra rằng chúng là tối ưu cho trường hợp cụ thể :

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

Đó là, có cả hai cột trong hai chỉ mục và không có chỉ mục một cột trên geolat và geolng là rất quan trọng.


1

Không có Đen và Trắng, một kích thước phù hợp với tất cả câu trả lời.

Bạn nên sử dụng một chỉ mục tổng hợp, khi tải công việc truy vấn của bạn sẽ được hưởng lợi từ một.

Bạn cần lập hồ sơ tải công việc truy vấn của bạn để xác định điều này.

Một chỉ mục tổng hợp xuất hiện khi các truy vấn có thể được thỏa mãn hoàn toàn từ chỉ mục đó.

CẬP NHẬT (để trả lời chỉnh sửa câu hỏi đã đăng): Nếu bạn đang chọn * từ bảng, chỉ mục tổng hợp có thể được sử dụng, thì có thể không. Bạn sẽ cần chạy EXPLAIN PLAN để chắc chắn.


Liệu nó có ý nghĩa để sử dụng một chỉ mục tổng hợp cho dữ liệu vị trí địa lý (vĩ độ và kinh độ)?
Teddy

1
Nó hoàn toàn phụ thuộc vào những truy vấn nào được thực hiện đối với bảng đó.
Mitch Wheat

Tôi đã cập nhật bài viết gốc của mình để bao gồm các truy vấn phổ biến nhất được thực hiện. Xem ở trên.
Teddy

1

Để thực hiện tìm kiếm không gian, bạn cần một thuật toán R-Tree , cho phép tìm kiếm các khu vực địa lý rất nhanh. Chính xác những gì bạn cần cho công việc này.

Một số cơ sở dữ liệu có các chỉ mục không gian được tích hợp. Một tìm kiếm nhanh của Google cho thấy MySQL 5 có chúng (nhìn vào SQL của bạn tôi đoán bạn đang sử dụng MySQL).


1

Chỉ mục tổng hợp có thể hữu ích khi bạn muốn tối ưu hóa group bymệnh đề (kiểm tra bài viết này http://dev.mysql.com/doc/refman/5.0/en/group-by-optimization.html ). Làm ơn chú ý:

Điều kiện tiên quyết quan trọng nhất để sử dụng các chỉ mục cho GROUP BY là tất cả các thuộc tính tham chiếu cột GROUP BY từ cùng một chỉ mục và chỉ mục lưu trữ các khóa của nó theo thứ tự (ví dụ: đây là chỉ mục BTREE chứ không phải chỉ mục HASH)


GROUP BYđã không được đề cập.
Rick James

Nó không được đề cập ở đâu? :) Nó rõ ràng được đề cập trong bài báo tôi đã đề cập. Và nó trả lời cho các câu hỏi đã được hỏi: Khi nào tôi nên sử dụng một chỉ mục tổng hợp trong cơ sở dữ liệu? Sự phân nhánh hiệu suất bằng cách sử dụng một chỉ số tổng hợp) là gì? Tại sao tôi nên sử dụng chỉ số tổng hợp?
Alexander

Sửa chữa: GROUP BYkhông được đề cập bởi OP.
Rick James

Chắc chắn, đó là câu trả lời - một trong những trường hợp khi chúng ta sẽ sử dụng một chỉ mục tổng hợp trong cơ sở dữ liệu.
Alexander

0

Tôi với @Mitch, phụ thuộc hoàn toàn vào các truy vấn của bạn. May mắn thay, bạn có thể tạo và xóa các chỉ mục bất cứ lúc nào và bạn có thể thêm từ khóa EXPLAIN vào các truy vấn của mình để xem bộ phân tích truy vấn có sử dụng các chỉ mục không.

Nếu bạn đang tìm kiếm một cặp lat / long chính xác thì chỉ số này có thể sẽ có ý nghĩa. Nhưng có lẽ bạn sẽ tìm nhà trong một khoảng cách nhất định của một địa điểm cụ thể, vì vậy các truy vấn của bạn sẽ trông giống như thế này (xem nguồn ):

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

và chỉ số rất có thể sẽ không hữu ích chút nào. Đối với các truy vấn không gian địa lý, bạn cần một cái gì đó như thế này .

Cập nhật: với truy vấn này:

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

Trình phân tích truy vấn có thể sử dụng một chỉ mục trên geolat một mình hoặc một chỉ mục trên geolng một mình hoặc có thể cả hai chỉ mục. Tôi không nghĩ rằng nó sẽ sử dụng một chỉ số tổng hợp. Nhưng thật dễ dàng để thử từng hoán vị trên một tập dữ liệu thực và sau đó (a) xem EXPLAIN nói gì với bạn và (b) đo thời gian thực sự truy vấn.


Tôi chỉ đơn giản là sử dụng muốn trở về nhà trong một lưới vuông. Tôi biết về không gian, vì vậy tôi không cố gắng tính toán khoảng cách. Tôi chỉ đơn giản muốn trả lại nhà trong lưới vuông và muốn điều đó được thực hiện nhanh chóng. Như vậy, tôi muốn chắc chắn rằng tôi đã thiết lập chỉ mục chính xác. cái đó có giúp ích không?
Teddy
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.