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

Memfilter hasil kueri MySQL diatur untuk menghasilkan beberapa kejadian dalam periode waktu tertentu

Jika kita ingin memfilter baris di mana tidak ada setidaknya empat baris sebelumnya dalam 60 detik terakhir, dengan asumsi bahwa dateTimeOrigination adalah tipe integer, stempel waktu gaya unix 32-bit, kita dapat melakukan sesuatu seperti ini:

SELECT FROM_UNIXTIME(r.dateTimeOrigination) AS dateTimeOrigination
     , r.callingPartyNumber
     , r.originalCalledPartyNumber
     , r.finalCalledPartyNumber
     , r.duration
     , r.origDeviceName
     , r.destDeviceName
  FROM cdr_records r
 WHERE r.dateTimeOrigination >= UNIX_TIMESTAMP('2016-05-20')
   AND r.dateTimeOrigination  < UNIX_TIMESTAMP('2016-05-21')
   AND r.callingPartyNumber NOT LIKE 'b00%'
   AND r.originalCalledPartyNumber NOT LIKE 'b00%'
   AND r.finalCalledPartyNumber NOT LIKE 'b00%'

   AND ( SELECT COUNT(1)
           FROM cdr_records c
          WHERE c.originalCalledPartyNumber = r.originalCalledPartyNumber
            AND c.dateTimeOrigination       > r.dateTimeOrigination - 60
            AND c.dateTimeOrigination      <= r.dateTimeOrigination
       ) > 4

 ORDER
    BY r.originalCalledPartyNumber
     , r.dateTimeOrigination

CATATAN:Untuk performa, kami lebih suka memiliki predikat pada kolom kosong.

Dengan bentuk seperti ini, dengan kolom yang dibungkus dengan ekspresi:

 WHERE FROM_UNIXTIME(r.dateTimeOrigination) LIKE '2016-05-20%'

MySQL akan mengevaluasi fungsi untuk setiap baris dalam tabel, lalu bandingkan hasil dari fungsi ke literal.

Dengan bentuk seperti ini:

 WHERE r.dateTimeOrigination >= UNIX_TIMESTAMP('2016-05-20')
   AND r.dateTimeOrigination  < UNIX_TIMESTAMP('2016-05-21')

MySQL akan mengevaluasi ekspresi di sisi kanan satu waktu, sebagai literal . Yang memungkinkan MySQL memanfaatkan operasi pemindaian rentang secara efektif pada indeks yang sesuai.

TINDAK LANJUT

Untuk kinerja terbaik dari kueri luar, indeks terbaik kemungkinan akan menjadi indeks dengan kolom terdepan dari dateTimeOrigination, sebaiknya berisi

... ON cdr_records (dateTimeOrigination
    ,callingPartyNumber,originalCalledPartyNumber,finalCalledPartyNumber)

Untuk kinerja terbaik, indeks penutup, untuk menghindari pencarian halaman di tabel yang mendasarinya. Misalnya:

... ON cdr_records (dateTimeOrigination
    ,callingPartyNumber,originalCalledPartyNumber,finalCalledPartyNumber
    ,duration,origDeviceName,destDeviceName)

Dengan itu, kami berharap EXPLAIN menampilkan "Menggunakan indeks".

Untuk subquery yang berkorelasi, kami menginginkan indeks dengan kolom utama seperti ini:

... ON cdr_records (originalCalledPartyNumber,dateTimeOrigination)

Saya sangat menyarankan Anda melihat output dari EXPLAIN untuk melihat indeks mana yang digunakan MySQL untuk kueri.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Masukkan data dari datepicker di database menggunakan php

  2. sql query untuk mengambil catatan 30 hari ke depan

  3. MySQL dan JDBC dengan rewriteBatchedStatements=true

  4. Tentukan apakah pernyataan sql dimulai dengan kata SELECT

  5. Bagaimana Anda menyandikan apostrof sehingga dapat dicari di mysql?