MySQL sebagai penyimpanan pesanan nilai kunci

Dokumen mengatakan bahwa:

Kebanyakan indeks MySQL (PRIMARY KEY, UNIQUE, INDEX, dan FULLTEXT) disimpan di B-tree.

Jadi secara fisik datanya sudah diurutkan berdasarkan kuncinya. Saya memerlukan skema nilai kunci di MySQL dengan dukungan kueri rentang: SELECT key, value FROM MyTable WHERE key >= key1 and key < key2;

Dalam banyak contoh (mayoritas) di web saya melihat orang menambahkan ORDER BY bahkan ketika memilih berdasarkan kunci utama.

Pertanyaan saya:

  • Apakah ORDER BY benar-benar diperlukan di sini agar hasilnya selalu terurut, dan jika ya - mengapa?
  • Apakah penyortiran akan memengaruhi kinerja atau akan dioptimalkan?
  • Apakah masuk akal untuk menjadikan nilai sebagai bagian dari indeks komposit jika nilainya tidak terlalu besar, misalnya. hanya angka?
  • Akankah SELECT key, value FROM MyTable WHERE key > key1 LIMIT 1; mengembalikan kunci berikutnya yang lebih besar dari kunci1, atau kunci apa pun yang lebih besar dari kunci1? Bagaimana cara mendapatkan pertanyaan titik LT,LE,GT,GE dengan andal?

(Saya membutuhkannya di MySQL karena alasan 'politik' dan perkakas sebelum pindah ke penyimpanan KV berbasis B+-tree lain yang ada, saya sudah memilih LMDB terbaik, jadi pertanyaannya hanya tentang mengejek skema di MySQL)


person V.B.    schedule 23.03.2015    source sumber
comment
Kalau di web pasti benar ;)   -  person nomistic    schedule 23.03.2015
comment
@nomistik Sarkasme? :) Setelah googling dan melihat banyak contoh saya sangat membutuhkan pemeriksaan kewarasan   -  person V.B.    schedule 23.03.2015
comment
Saya bukan ahli dalam hal ini, jadi saya akan menghindari menjawab pertanyaan tersebut, tetapi menerapkan order by harus selalu memiliki efek netral atau negatif pada kueri ini. Pada kolom yang tidak diindeks, pengurutan kasus terbaik selalu O(n log n), sedangkan pemeriksaan setiap record dengan pemindaian tabel penuh adalah O(n). Pada kolom terindeks yang disimpan dalam B-Tree, pengurutan tidak akan berpengaruh jika menggunakan operator perbandingan yang sama, dan akan berdampak negatif jika menggunakan operator perbandingan yang berbeda.   -  person Nick Bailey    schedule 23.03.2015
comment
ya maaf. Pemahaman saya untuk bagian pertama adalah bahwa hal itu dilakukan berdasarkan kebiasaan dan praktik pengkodean yang baik (masuk akal jika itu bukan kunci utama). Selain itu, terkadang kunci utama bukan numerik (seperti tipe variabel type_code... Saya sering menggunakan ini untuk tabel dengan tingkat kontrol tertentu untuk mempercepat kemudahan kueri, tetapi dalam hal ini saya biasanya akan memesan berdasarkan nilainya, dan bukan kodenya). Kadang-kadang saya akan memesan dengan dua entri. Maaf, saya tidak tahu tentang kinerjanya, tapi menurut saya kinerjanya minimal. Tidak tahu tentang bagian terakhir.   -  person nomistic    schedule 23.03.2015


Jawaban (1)


  • #P1#
    #P2# #P3#
  • #P4#
    #P5# #P6# #P7#
  • #P8#
    #P9# #P10#
  • #P11#
    #P12# #P13#
    SELECT key, value FROM MyTable WHERE key > key1 ORDER BY key LIMIT 1
    
    #P14#
    SELECT key, value FROM MyTable WHERE key <= key1 ORDER BY key DESC LIMIT 1
    
person eggyal    schedule 23.03.2015
comment
Terima kasih! Saya memerlukan kebenaran terlebih dahulu - untuk mendapatkan nilai yang selalu diurutkan berdasarkan kunci (Saya telah memperbarui pertanyaan dan menambahkan subpertanyaan lain - bisakah Anda mengomentari pertanyaan ke-4?). Pada saat yang sama, saya tidak ingin melakukan sesuatu yang bodoh sehingga selama kueri, urutan pohon B yang ada akan rusak dan saya harus menerapkan kembali ORDER BY dengan overhead-nya. Ini terutama tiruan untuk waktu desain, tetapi volume data belum terlalu besar dan MySQL bisa bertahan lama, saya hanya perlu menyembunyikan penyimpanan di belakang antarmuka dan mendapatkan perilaku yang persis sama seperti B-tree biasa. Anehnya, MySQL menyembunyikannya. - person V.B.; 23.03.2015
comment
Keren, terima kasih banyak! Hanya karena penasaran: untuk poin ke-4, menurut Anda apakah, mis. InnoDB, pengoptimal cukup pintar untuk hanya melakukan pencarian biner dan memindahkan berikutnya/sebelumnya alih-alih memilih semua kunci yang lebih besar/lebih kecil lalu mengurutkannya dan kemudian mengambil yang pertama? Atau EXPLAIN akan menunjukkan ini juga? - person V.B.; 23.03.2015
comment
@V.B.: Lihat Mengoptimalkan Kueri LIMIT—Jika Anda menggabungkan LIMIT row_count dengan ORDER BY , MySQL mengakhiri penyortiran segera setelah menemukan row_count baris pertama dari hasil yang diurutkan, daripada mengurutkan seluruh hasil. Jika pemesanan dilakukan dengan menggunakan indeks, ini sangat cepat... Segera setelah MySQL mengirimkan jumlah baris yang diperlukan ke klien, MySQL akan membatalkan kueri kecuali Anda menggunakan SQL_CALC_FOUND_ROWS. - person eggyal; 23.03.2015