Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Jak znaleźć luki w danych szeregów czasowych w MySQL?

Na początek podsumujmy liczbę wpisów w Twojej tabeli według godzin.

SELECT CAST(DATE_FORMAT(entry_time,'%Y-%m-%d %k:00:00') AS DATETIME) hour,
       COUNT(*) samplecount
  FROM table
 GROUP BY CAST(DATE_FORMAT(entry_time,'%Y-%m-%d %k:00:00') AS DATETIME)

Teraz, jeśli rejestrujesz coś co sześć minut (dziesięć razy na godzinę), wszystkie wartości liczby próbek powinny wynosić dziesięć. To wyrażenie:CAST(DATE_FORMAT(entry_time,'%Y-%m-%d %k:00:00') AS DATETIME) wygląda na owłosioną, ale po prostu skraca znaczniki czasu do godziny, w której występują, wyzerowując minutę i sekundę.

Jest to dość wydajne i pozwoli Ci zacząć. Jest to bardzo wydajne, jeśli możesz umieścić indeks w kolumnie entry_time i ograniczyć zapytanie do, powiedzmy, wczorajszych próbek, jak pokazano tutaj.

SELECT CAST(DATE_FORMAT(entry_time,'%Y-%m-%d %k:00:00') AS DATETIME) hour,
       COUNT(*) samplecount
  FROM table
 WHERE entry_time >= CURRENT_DATE - INTERVAL 1 DAY
   AND entry_time < CURRENT_DATE
 GROUP BY CAST(DATE_FORMAT(entry_time,'%Y-%m-%d %k:00:00') AS DATETIME)

Ale nie jest zbyt dobry w wykrywaniu całych godzin, które mijają z brakującymi próbkami. Jest też trochę wrażliwy na jitter w twoim samplu. Oznacza to, że jeśli próbka z najwyższej półki jest czasami o pół sekundy za wcześnie (10:59:30), a czasami o pół sekundy za późno (11:00:30), liczniki godzinowego podsumowania będą wyłączone. Tak więc to podsumowanie godzinowe (lub podsumowanie dzienne lub podsumowanie minutowe itp.) Nie jest kuloodporne.

Potrzebujesz zapytania samozłączającego, aby wszystko było idealnie poprawne; jest trochę bardziej podobny do kuli włosowej i nie jest tak wydajny.

Zacznijmy od stworzenia sobie wirtualnej tabeli (podzapytania) z ponumerowanymi próbkami. (To jest kłopotliwe w MySQL; niektóre inne drogie DBMS-y ułatwiają to. Nieważne.)

  SELECT @sample:[email protected]+1 AS entry_num, c.entry_time, c.value
    FROM (
        SELECT entry_time, value
      FROM table
         ORDER BY entry_time
    ) C,
    (SELECT @sample:=0) s

Ta mała wirtualna tabela podaje numer_wpisu, czas_wpisu, wartość.

W następnym kroku łączymy go ze sobą.

SELECT one.entry_num, one.entry_time, one.value, 
       TIMEDIFF(two.value, one.value) interval
  FROM (
     /* virtual table */
  ) ONE
  JOIN (
     /* same virtual table */
  ) TWO ON (TWO.entry_num - 1 = ONE.entry_num)

Spowoduje to wyrównanie kolejnych dwóch tabel z przesunięciem o jeden wpis, zgodnie z klauzulą ​​ON JOIN.

Na koniec wybieramy wartości z tej tabeli z interval większe niż próg, a czasy próbek znajdują się tuż przed brakującymi.

Oto kwerenda over all self join. Mówiłem ci, że to kula włosowa.

SELECT one.entry_num, one.entry_time, one.value, 
       TIMEDIFF(two.value, one.value) interval
  FROM (
    SELECT @sample:[email protected]+1 AS entry_num, c.entry_time, c.value
      FROM (
          SELECT entry_time, value
            FROM table
           ORDER BY entry_time
      ) C,
      (SELECT @sample:=0) s
  ) ONE
  JOIN (
    SELECT @sample2:[email protected]+1 AS entry_num, c.entry_time, c.value
      FROM (
          SELECT entry_time, value
            FROM table
           ORDER BY entry_time
      ) C,
      (SELECT @sample2:=0) s
  ) TWO ON (TWO.entry_num - 1 = ONE.entry_num)

Jeśli musisz to zrobić w środowisku produkcyjnym na dużej tabeli, możesz to zrobić dla podzbioru danych. Na przykład możesz to zrobić każdego dnia dla próbek z poprzednich dwóch dni. Byłoby to całkiem wydajne, a także zapewniłoby, że nie przeoczysz żadnych brakujących próbek tuż o północy. Aby to zrobić, Twoje małe wirtualne stoły o numerach rzędów będą wyglądać tak.

  SELECT @sample:[email protected]+1 AS entry_num, c.entry_time, c.value
    FROM (
        SELECT entry_time, value
      FROM table
         ORDER BY entry_time
         WHERE entry_time >= CURRENT_DATE - INTERVAL 2 DAY
           AND entry_time < CURRENT_DATE /*yesterday but not today*/
    ) C,
    (SELECT @sample:=0) s


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jaki jest najlepszy sposób obsługi sesji dla witryny PHP na wielu hostach?

  2. mysql - Tworzenie wierszy a wydajność kolumn

  3. Dane zostały obcięte dla kolumny?

  4. Hibernacja mapowania relacji/przyspieszenie wstawiania partii

  5. Zatwierdzenie i transakcja MySQL