Mysql
 sql >> Teknologi Basis Data >  >> RDS >> Mysql

Bergabung pada indeks mysql spasial

Saya percaya itu karena MySQL tidak mendukung penggabungan indeks spasial. Tidak yakin apakah itu masih benar tetapi saya pernah membacanya di suatu tempat di masa lalu. Jika Anda memiliki pernyataan OR, maka indeks spasial tidak digunakan

Dalam kasus Anda, di mana Anda melakukan poin.id =1, itu adalah pemilihan langsung dengan satu hasil yang dikembalikan yang digunakan dalam mbrcontains. Itu menggunakan indeks.

Saat Anda menambahkan points.in (1,2,3), yang mengembalikan 3 hasil dan masing-masing perlu dipetakan ke tabel rentang, oleh karena itu tidak berfungsi

hasil

id  select_type     table   type    possible_keys   key     key_len     ref     rows    filtered    Extra
1   SIMPLE  points  range   PRIMARY     PRIMARY     4   NULL    3   100.00  Using where
1   SIMPLE  ranges  ALL     poly    NULL    NULL    NULL    6467418     100.00   

Anda dapat menyederhanakan pengujian Anda tanpa tabel poin dengan melakukan ini:SELECT * FROM ranges where mbrcontains( poly, GEOMFROMWKB(POINT(0, 0)))

id  select_type     table   type    possible_keys   key     key_len     ref     rows    filtered    Extra
1   SIMPLE  ranges  range   poly    poly    34  NULL    1   100.00  Using where

Dan sekarang ini; SELECT * FROM rentang di mana mbrcontains( poly, GEOMFROMWKB(POINT(0, 0))) OR mbrcontains( poly, GEOMFROMWKB(POINT(10, 10)))

hasil

id  select_type     table   type    possible_keys   key     key_len     ref     rows    filtered    Extra
1   SIMPLE  ranges  ALL     poly    NULL    NULL    NULL    6467418     100.00  Using where

Lihat bahwa dalam kasus kedua, Anda tidak menggunakan indeks dan hanya memindai.

Anda dapat memaksa kueri untuk menggunakan indeks dengan membuat UNION untuk setiap titik tertentu, tetapi saya tidak yakin apakah itu akan lebih cepat. Saya melakukan beberapa pengujian secara lokal dan itu sedikit lebih lambat dari kueri pertama Anda.

EXPLAIN EXTENDED 
SELECT *
FROM points
FORCE INDEX (PRIMARY )
LEFT JOIN ranges
FORCE INDEX ( poly ) ON mbrcontains( poly, point )
WHERE points.id = 1
UNION DISTINCT
SELECT *
FROM points
FORCE INDEX (PRIMARY )
LEFT JOIN ranges
FORCE INDEX ( poly ) ON mbrcontains( poly, point )
WHERE points.id = 2
UNION DISTINCT
SELECT *
FROM points
FORCE INDEX (PRIMARY )
LEFT JOIN ranges
FORCE INDEX ( poly ) ON mbrcontains( poly, point )
WHERE points.id = 3

hasil

id  select_type     table   type    possible_keys   key     key_len     ref     rows    filtered    Extra
1   PRIMARY     points  const   PRIMARY     PRIMARY     4   const   1   100.00   
1   PRIMARY     ranges  range   poly    poly    34  NULL    1   100.00  Using where
2   UNION   points  const   PRIMARY     PRIMARY     4   const   1   100.00   
2   UNION   ranges  range   poly    poly    34  NULL    1   100.00  Using where
3   UNION   points  const   PRIMARY     PRIMARY     4   const   1   100.00   
3   UNION   ranges  range   poly    poly    34  NULL    1   100.00  Using where
NULL    UNION RESULT    <union1,2,3>    ALL     NULL    NULL    NULL    NULL    NULL    NULL     


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Cara menyembunyikan kolom alias di mysql EDITED

  2. Dasar-dasar sistem ingat-saya

  3. PDO + MySQL dan pengkodean UTF-8 yang rusak

  4. Memasukkan data Biner ke MySQL (tanpa PreparedStatement)

  5. Formulir pendaftaran dengan php, mysql