Saat ini saya mencoba menjalankan beberapa query terhadap data dump komentar Stack Overflow. Seperti apa skema ini:
CREATE TABLE `socomments` (
`Id` int(11) NOT NULL,
`PostId` int(11) NOT NULL,
`Score` int(11) DEFAULT NULL,
`Text` varchar(600) NOT NULL,
`CreationDate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`UserId` int(11) NOT NULL,
PRIMARY KEY (`Id`),
KEY `idx_socomments_PostId` (`PostId`),
KEY `CreationDate` (`CreationDate`),
FULLTEXT KEY `Text` (`Text`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
Saya menjalankan kueri ini terhadap tabel, dan berjalan sangat lambat (Memang memiliki 29 juta baris, tetapi memiliki indeks Teks Lengkap):
SELECT *
FROM socomments
WHERE MATCH (Text) AGAINST ('"fixed the post"' IN BOOLEAN MODE)
Jadi saya membuat profilnya, hasilnya adalah:
|| Status || Duration ||
|| starting || 0.000058 ||
|| checking permissions || 0.000006 ||
|| Opening tables || 0.000014 ||
|| init || 0.000019 ||
|| System lock || 0.000006 ||
|| optimizing || 0.000007 ||
|| statistics || 0.000013 ||
|| preparing || 0.000005 ||
|| FULLTEXT initialization || 207.1112 ||
|| executing || 0.000009 ||
|| Sending data || 0.000856 ||
|| end || 0.000004 ||
|| query end || 0.000004 ||
|| closing tables || 0.000006 ||
|| freeing items || 0.000059 ||
|| logging slow query || 0.000037 ||
|| cleaning up || 0.000046 ||
Seperti yang Anda lihat, ini menghabiskan waktu yang lama dalam inisialisasi FULLTEXT. Apakah ini normal? Jika tidak, bagaimana saya memperbaikinya?
mysql
innodb
full-text-search
hichris123
sumber
sumber
id_group 2
danid_group 23
. Dengan ini pencarian Anda di dalam tabel utama Anda dan batasi permintaan Anda untuk rentang id 2.000 hingga 2.999 dan 23.000 hingga 23.999. Tentu saja yang ke-2 akan menghasilkan lebih banyak hasil sesuai kebutuhan ketika Anda menggabungkan semua komentar membuat kombinasi kata kunci baru, tetapi akhirnya akan mempercepat semuanya. Tentu saja itu menggandakan penggunaan ruang disk. Komentar baru harus CONCAT'ed ke tabel grup.Jawaban:
Yang lain menganggap ini situasi yang merepotkan
Karena Dokumentasi MySQL sangat singkat tentang status utas ini
satu-satunya jalan Anda adalah membuat persiapan dengan lebih sedikit data. Bagaimana?
SARAN # 1
Lihatlah permintaan Anda lagi. Itu memilih semua kolom. Saya akan menolak permintaan untuk mengumpulkan hanya kolom id dari
socomments
. Kemudian, gabungkan id yang diambil kembali kesocomments
tabel.Ini mungkin menghasilkan rencana EXPLAIN yang lebih buruk tetapi saya pikir profiling akan berubah menjadi lebih baik. Ide dasarnya adalah: Jika Anda memiliki Pencarian FULLTEXT yang agresif, buatlah mengumpulkan data dengan jumlah paling sedikit selama
FULLTEXT initialization
fase itu, sehingga mengurangi waktu.Saya telah merekomendasikan ini berkali-kali sebelumnya
May 14, 2012
: kueri lambat dengan teks lengkap dan gabung kiriMar 18, 2012
: Mengapa LIKE lebih dari 4x lebih cepat dari MATCH ... MELAWAN indeks FULLTEXT di MySQL?Jan 26, 2012
: Mysql pencarian teks lengkap optimasi my.cnf :Oct 25, 2011
: Indeks FULLTEXT diabaikan dalam MODE BOOLEAN dengan persyaratan 'jumlah kata'SARAN # 2
Pastikan Anda mengatur opsi FULLTEXT berbasis InnoDB, bukan yang untuk MyISAM. Dua opsi yang harus Anda perhatikan adalah
Pikirkan sejenak. Bidang teks adalah VARCHAR (600). Katakanlah rata-rata adalah 300 byte. Anda memiliki 29.000.000.000 dari mereka. Itu akan menjadi sedikit 8GB. Mungkin meningkatkan innodb_ft_cache_size dan innodb_ft_total_cache_size juga dapat membantu.
Pastikan Anda memiliki cukup RAM untuk buffer InnoDB FULLTEXT yang lebih besar.
COBALAH !!!
sumber
SELECT B.* FROM (SELECT id FROM socomments WHERE MATCH (Text) AGAINST ('+"fixed the post"' IN BOOLEAN MODE)) A LEFT JOIN socomments B USING (id);
dan lihat apakah itu membuat perbedaan.A leading or trailing plus sign indicates that this word must be present in each row that is returned. InnoDB only supports leading plus signs.
Dalam kasus khusus Anda, frasa yang tepatfixed the post
harus ada.Jika Anda menggunakan indeks InnoDB FULLTEXT, kueri akan sering menggantung dalam keadaan "inisialisasi FULLTEXT" jika Anda menanyakan tabel yang memiliki banyak baris yang dihapus. Dalam implementasi FULLTEXT InnoDB, baris yang dihapus tidak dipangkas sampai operasi OPTIMIZE berikutnya dijalankan terhadap tabel yang terpengaruh. Lihat: https://dev.mysql.com/doc/refman/5.6/id/innodb-fulltext-index.html
Seseorang juga dapat memeriksa jumlah catatan yang dihapus tetapi tidak dibersihkan dengan menanyakan informasi_schema.innodb_ft_deleted
Untuk mengatasi ini, orang harus menjalankan TABEL OPTIMASI secara teratur terhadap tabel dengan indeks InnoDB FULLTEXT.
sumber
innodb_optimize_fulltext_only=1
dan sebuahOPTIMIZE
tabel benar-benar menangani baris yang dihapus "dalam menunggu"? dba.stackexchange.com/questions/174486/…Ada bug yang dikonfirmasi di MySQL ( Dihapus DOCID tidak dikelola selama MENGOPTIMASI tabel InnoDB FULLTEXT ) yang kinerja tangki di bawah beban hapus yang besar (tanpa membangun kembali tabel dari awal).
Terkait .
sumber
Indeks teks lengkap di MySQL tidak dirancang untuk mendukung data dalam jumlah besar sehingga kecepatan pencarian menurun cukup cepat saat dataset Anda tumbuh dewasa. Salah satu solusinya adalah dengan menggunakan mesin pencarian teks lengkap eksternal seperti Solr atau Sphinx yang telah meningkatkan fungsionalitas pencarian (pencarian relevansi dan dukungan pencarian frasa, aspek bawaan, snippet, dll.) Sintaks kueri yang diperluas dan kecepatan lebih cepat pada pertengahan hingga set data besar.
Solr didasarkan pada platform Java jadi jika Anda menjalankan aplikasi berbasis Java akan menjadi pilihan alami untuk Anda, Sphinx ditulis pada C ++ dan bertindak sebagai daemon dengan cara yang sama seperti MySQL. Segera setelah Anda memberi makan mesin eksternal dengan data yang ingin Anda cari, Anda juga dapat memindahkan beberapa pertanyaan dari MySQL. Saya tidak dapat memberi tahu Anda mesin mana yang lebih baik dalam kasus Anda, saya menggunakan sebagian besar Sphinx dan di sini adalah contoh penggunaan: http://astellar.com/2011/12/replacing-mysql-full-text-search-with-sphinx/
sumber