Mysql
 sql >> база данни >  >> RDS >> Mysql

Филтриране на набор от резултати от MySQL заявка за получаване на множество повторения в рамките на определен период от време

Ако искаме да филтрираме редовете, в които няма поне четири предходни реда през последните 60 секунди, като приемем, че dateTimeOrigination е целочислен тип, 32-битов времеви печат в стил unix, можем да направим нещо подобно:

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

ЗАБЕЛЕЖКА:За производителност предпочитаме да имаме предикати върху голи колони.

С форма като тази, с колона, обвита в израз:

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

MySQL ще оцени функцията за всеки ред в таблицата и след това сравнете връщането от функцията към литерала.

С формуляр като този:

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

MySQL ще оцени изразите от дясната страна едно време, като литерал . Което позволява на MySQL да използва ефективно операция за сканиране на диапазон върху подходящ индекс.

ПОСЛЕДВАНЕ

За най-добра производителност на външната заявка, най-добрият индекс вероятно би бил индекс с водеща колона на dateTimeOrigination, за предпочитане съдържаща

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

За най-добра производителност, покриващ индекс, за да се избегнат търсения на страниците в основната таблица. Например:

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

С това бихме очаквали EXPLAIN да покаже „Използване на индекс“.

За корелираната подзаявка бихме искали индекс с водещи колони като този:

... ON cdr_records (originalCalledPartyNumber,dateTimeOrigination)

Горещо ви препоръчвам да погледнете изхода от EXPLAIN, за да видите кои индекси MySQL използва за заявката.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Заявете конкретна стойност с обобщена таблица mySQL

  2. Защо PHP скриптът не успява да се вмъкне в MySQL база данни?

  3. как да разбера дали колоната е първичен ключ с помощта на mysqli?

  4. MYSQL таблица със статични стойности и динамични стойности

  5. Използване на 'end' като име на колона в Ruby on Rails (MySQL)