Penemuduga: Bagaimanakah anda menanyakan 10 juta data?
Baru-baru ini, saya telah melakukan temu bual olok-olok dan pengoptimuman semula untuk semua orang, dan saya mendapati ramai orang menjadi lemah pada lutut apabila melihat soalan seperti berpuluh juta data.
Mungkin sesetengah orang tidak pernah menemui jadual dengan berpuluh juta data dan mereka tidak tahu apa yang akan berlaku apabila menanyakan berpuluh juta data.
Hari ini saya akan membawa anda melalui latihan praktikal Kali ini berdasarkan MySQL 5.7.26 untuk ujian
Menyediakan data
Apa yang perlu dilakukan jika anda tiada data. ?
Anda tidak boleh menciptanya sendiri tanpa data?
Adakah sukar untuk mencipta data?
10 juta penciptaan kod?
Itu mustahil, ia terlalu perlahan, ia mungkin benar-benar membawa anda sehari suntuk untuk berlari. Anda boleh menggunakan skrip pangkalan data untuk melaksanakan dengan lebih pantas.
Create Table
CREATE TABLE `user_operation_log` ( `id` int(11) NOT NULL AUTO_INCREMENT, `user_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, `ip` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, `op_data` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, `attr1` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, `attr2` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, `attr3` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, `attr4` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, `attr5` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, `attr6` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, `attr7` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, `attr8` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, `attr9` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, `attr10` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, `attr11` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, `attr12` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;e
Create Script Data Siscion Batch, kecekapan akan lebih cepat, dan setiap 1000 item akan dilakukan. sisipan kelompok juga akan menjadi perlahan
Mulakan ujian Konfigurasi komputer saya agak rendah: sanga tekanan standard win10 i5, baca dan tulis kira-kira 500MB SSD
hanya 3148000 keping data disediakan untuk ujian ini, menduduki cakera itu 5G (belum pengindeksan), dan ia berjalan selama 38 minit Pelajar dengan konfigurasi komputer yang baik boleh memasukkan berbilang titik data untuk ujian
SELECT count(1) FROM `user_operation_log`
Kembalikan keputusan: 3148000
.Tiga masa pertanyaan ialah:
14060 ms 13755 ms 13447 ms
普通分页查询
MySQL 支持 LIMIT 语句来选取指定的条数数据, Oracle 可以使用 ROWNUM 来选取。
MySQL分页查询语法如下:
SELECT * FROM table LIMIT [offset,] rows | rows OFFSET offset
第一个参数指定第一个返回记录行的偏移量 第二个参数指定返回记录行的最大数目
下面我们开始测试查询结果:
SELECT * FROM `user_operation_log` LIMIT 10000, 10
查询3次时间分别为:
59 ms 49 ms 50 ms
这样看起来速度还行,不过是本地数据库,速度自然快点。
换个角度来测试
相同偏移量,不同数据量
SELECT * FROM `user_operation_log` LIMIT 10000, 10 SELECT * FROM `user_operation_log` LIMIT 10000, 100 SELECT * FROM `user_operation_log` LIMIT 10000, 1000 SELECT * FROM `user_operation_log` LIMIT 10000, 10000 SELECT * FROM `user_operation_log` LIMIT 10000, 100000 SELECT * FROM `user_operation_log` LIMIT 10000, 1000000
查询时间如下:
Kuantiti | Kali pertama | Kali kedua | Kali ketiga | ||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
10 item | 5ms | ||||||||||||||||||||||||||||||||||||||||||||||||||||
50ms | 60ms | 55ms | |||||||||||||||||||||||||||||||||||||||||||||||||||
61ms | 74ms | 60ms | |||||||||||||||||||||||||||||||||||||||||||||||||||
164ms | ms180ms | 100000 item | |||||||||||||||||||||||||||||||||||||||||||||||||||
1741ms | 1764ms | 1000000 item | |||||||||||||||||||||||||||||||||||||||||||||||||||
16889ms | 17081ms | 从上面结果可以得出结束:数据量越大,花费时间越长 相同数据量,不同偏移量SELECT * FROM `user_operation_log` LIMIT 100, 100 SELECT * FROM `user_operation_log` LIMIT 1000, 100 SELECT * FROM `user_operation_log` LIMIT 10000, 100 SELECT * FROM `user_operation_log` LIMIT 100000, 100 SELECT * FROM `user_operation_log` LIMIT 1000000, 100
从上面结果可以得出结束:偏移量越大,花费时间越长 SELECT * FROM `user_operation_log` LIMIT 100, 100 SELECT id, attr FROM `user_operation_log` LIMIT 100, 100 如何优化既然我们经过上面一番的折腾,也得出了结论,针对上面两个问题:偏移大、数据量大,我们分别着手优化 优化偏移量大问题采用子查询方式我们可以先定位偏移位置的 id,然后再查询数据 SELECT * FROM `user_operation_log` LIMIT 1000000, 10 SELECT id FROM `user_operation_log` LIMIT 1000000, 1 SELECT * FROM `user_operation_log` WHERE id >= (SELECT id FROM `user_operation_log` LIMIT 1000000, 1) LIMIT 10 查询结果如下:
从上面结果得出结论:
缺点:只适用于id递增的情况 id非递增的情况可以使用以下写法,但这种缺点是分页查询只能放在子查询里面 注意:某些 mysql 版本不支持在 in 子句中使用 limit,所以采用了多个嵌套select SELECT * FROM `user_operation_log` WHERE id IN (SELECT t.id FROM (SELECT id FROM `user_operation_log` LIMIT 1000000, 10) AS t) 采用 id 限定方式这种方法要求更高些,id必须是连续递增,而且还得计算id的范围,然后使用 between,sql如下 SELECT * FROM `user_operation_log` WHERE id between 1000000 AND 1000100 LIMIT 100 SELECT * FROM `user_operation_log` WHERE id >= 1000000 LIMIT 100 查询结果如下:
从结果可以看出这种方式非常快 注意:这里的 LIMIT 是限制了条数,没有采用偏移量 优化数据量大问题返回结果的数据量也会直接影响速度 SELECT * FROM `user_operation_log` LIMIT 1, 1000000 SELECT id FROM `user_operation_log` LIMIT 1, 1000000 SELECT id, user_id, ip, op_data, attr1, attr2, attr3, attr4, attr5, attr6, attr7, attr8, attr9, attr10, attr11, attr12 FROM `user_operation_log` LIMIT 1, 1000000 查询结果如下:
Dapat dilihat daripada keputusan bahawa dengan mengurangkan lajur yang tidak diperlukan, kecekapan pertanyaan juga boleh dipertingkatkan dengan ketara Kelajuan pertanyaan pertama dan ketiga adalah hampir sama Pada masa ini, anda pasti akan mengeluh, jadi mengapa saya perlu tulis begitu banyak medan? , hanya * dan anda sudah selesai Perhatikan bahawa pelayan dan klien MySQL saya berada pada mesin yang sama, jadi data pertanyaan serupa boleh menguji klien dan MySQL secara berasingan PILIH *. Sedap tak baunya?Dengan cara ini, saya ingin menambah di sini mengapa kita harus mengharamkan 主要两点:
SELECT * " Pangkalan data perlu menghuraikan lebih banyak objek, medan, kebenaran, atribut, dsb. Kandungan, apabila pernyataan SQL adalah kompleks dan terdapat banyak penghuraian keras, ia akan menyebabkan beban berat pada pangkalan data. * Kadangkala log, IconMD5 dan seumpamanya tersilap dimasukkan Useless and large medan teks, saiz penghantaran data akan meningkat secara eksponen. Terutama kerana MySQL dan aplikasi tidak berada pada mesin yang sama, overhed ini sangat jelas. Atas ialah kandungan terperinci Penemuduga: Bagaimanakah anda menanyakan 10 juta data?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP! Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
![]() Alat AI Hot![]() Undress AI ToolGambar buka pakaian secara percuma ![]() Undresser.AI UndressApl berkuasa AI untuk mencipta foto bogel yang realistik ![]() AI Clothes RemoverAlat AI dalam talian untuk mengeluarkan pakaian daripada foto. ![]() Clothoff.ioPenyingkiran pakaian AI ![]() Video Face SwapTukar muka dalam mana-mana video dengan mudah menggunakan alat tukar muka AI percuma kami! ![]() Artikel Panas
Skop pembolehubah PHP dijelaskan
4 minggu yang lalu
By 百草
Mengulas kod dalam php
3 minggu yang lalu
By 百草
Petua untuk menulis komen php
3 minggu yang lalu
By 百草
<🎜>: Tumbuh Taman - Panduan Lengkap untuk Melancong Pedagang
3 minggu yang lalu
By Jack chen
Di sini ' s Apabila OnePlus anda akan mendapat Android 16 (Oxygenos 16)
1 bulan yang lalu
By DDD
![]() Alat panas![]() Notepad++7.3.1Editor kod yang mudah digunakan dan percuma ![]() SublimeText3 versi CinaVersi Cina, sangat mudah digunakan ![]() Hantar Studio 13.0.1Persekitaran pembangunan bersepadu PHP yang berkuasa ![]() Dreamweaver CS6Alat pembangunan web visual ![]() SublimeText3 versi MacPerisian penyuntingan kod peringkat Tuhan (SublimeText3) ![]() Testthepdfinanotherapptodetermineiftheisseiswiththefileoredge.2.enableTetHEBuilt-Inpdfviewerbyturningoff "AlwaysopenpdffileseXternally" dan "muat turun" inedgesettings.3.clearbrowsdataincludingcookiesandcookiescookiesandcookiescookiesandcookiescookieshincookieshincookiescookiescookiescookiescookiescookiescookiescookiescookiescokiescookiescookiescookiescookiescookiescooker ![]() Importjava.ioandjava.net.socketfFori ![]() Aplikasi Java Containerized: Buat Dockerfile, gunakan imej asas seperti Eclipse-Temurin: 17-jre-alpine, salin fail balang dan tentukan perintah permulaan, bina imej melalui Dockerbuild dan lari secara tempatan dengan Dockerrun. 2. Tolak imej ke Registry Container: Gunakan Dockertag untuk menandakan imej dan menolaknya ke DockerHub dan pendaftaran lain. Anda mesti log masuk terlebih dahulu ke Dockerlogin. 3. Digunakan ke Kubernet: Tulis Deployment.yaml Untuk menentukan penggunaan, tetapkan bilangan replika, imej kontena dan sekatan sumber, dan tulis perkhidmatan.yaml untuk membuat ![]() Di VSCode, anda boleh menukar kawasan panel dan penyuntingan dengan cepat melalui kekunci pintasan. Untuk melompat ke panel Explorer kiri, gunakan CTRL Shift E (Windows/Linux) atau CMD Shift E (MAC); Kembali ke kawasan penyuntingan untuk menggunakan Ctrl `atau ESC atau Ctrl 1 ~ 9. Berbanding dengan operasi tetikus, pintasan papan kekunci lebih cekap dan tidak mengganggu irama pengekodan. Petua lain termasuk: Kotak carian fokus Ctrl Kctrl e, fail menamakan semula F2, memadam fail, masukkan fail terbuka, arrow kunci memperluas/runtuh folder. ![]() RuntheWindowsUpdateTroubleshooterviaSettings>Update&Security>Troubleshoottoautomaticallyfixcommonissues.2.ResetWindowsUpdatecomponentsbystoppingrelatedservices,renamingtheSoftwareDistributionandCatroot2folders,thenrestartingtheservicestocle ![]() AwhileloopinjavarepeatedlyexecutescodeaslongasthecondeConditionistrue; 2.InitializeAcontrolvariableBeforetheloop; 3.DefinetheloopcondusingAbeaneanExpression; ![]() Javaserializationconvertsanobject'sstateintoabytestreamforstorageortransmission, anddeserialization reconstructstheobjectfromhattstream.1.toenableserialization, aclassmustimplementtheserializableInterfe.2.useObjectStreamtoserialialization.useObjectStreamtoserialialization.useObjectStreamtosererialialize. ![]() Numpy adalah perpustakaan teras untuk pengkomputeran saintifik di Python. Adalah baik untuk mengendalikan operasi algebra linear dan menyediakan array dan fungsi ndarray yang cekap dalam modul numpy.linalg. 1. Gunakan np.linalg.solve (a, b) untuk menyelesaikan sistem persamaan linear Ax = b untuk mendapatkan vektor penyelesaian x; 2. Transposisi matriks dilaksanakan melalui A.T; 3. Pendaraban matriks boleh digunakan untuk np.dot (a, b) atau a@b; 4. Matrix songsang dikira oleh np.linalg.inv (a), dan matriks perlu diterbalikkan; 5. Penentu diberikan oleh Np.Linalg.Det (A); 6. Eigenvalue dan eigenvector diperoleh melalui np.linalg.eig (a), dan eigenvector telah dinormalisasi; ![]() |