Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Zliczanie unikalnych wartości
Forum PHP.pl > Forum > Bazy danych > MySQL
snapshot
Chcę wyciągnąć ilość unikalnych osób, które głosowały. Zakładamy, że użytkownik może głosować kilka razy.
  1. SELECT COUNT(DISTINCT user) FROM vote WHERE type = 5

Powyższe zapytanie działa tak jak chcę, jednak czas wykonywania jest nie do zaakceptowania i wynosi 0.8-1.0 sekundy. Dodam, że tabela posiada aktualnie około 600 000 rekordów. Da się szybciej? smile.gif
nospor
a masz założony index na type?
Crozin
Zapewne masz jakąś tabelę która reprezentuje sondę na którą mogą głosować użytkownicy, tak? Dodaj do niej dwie kolumny total_votes oraz total_unique_votes. Następnie dodaj sobie wyzwalacz, który po dodaniu rekordu do tabeli vote zwiększy wartości obu kolumn i analogicznie przy usunięciu zmniejszy je. Dzięki temu w ogóle nie będziesz musiał dynamicznie zliczać tych głosów.

EDIT: Dopiero teraz zauważyłem "type = 5" - w takim razie raczej powyższe będzie bezużyteczne.
wookieb
Jak już to na type, user (2 kolumny w jednym indeksie)
snapshot
Wpadłem na to sam @wookieb i faktycznie działa. Mam teraz 0.02. Dzięki. Jednak mam kolejny problem. Muszę podczas realizacji innego scenariusza (unikalne grupy) podłączyć inną tabelę:
  1. SELECT COUNT(DISTINCT u.team) FROM vote v INNER JOIN user u USING(user) WHERE v.type = 5

Czas wykonywania to znowu ~1 sekundy. Analogicznie dodałbym index na dwóch kolumnach w dwóch różnych tabelach, ale chyba się nie da...
wookieb
Tabela user ma index na "user"?
user to login czy id usera? Jezeli login to zacznij używać id.
Silnik tabel polecam ustawić na INNODB.
snapshot
Kolumna user w tabli user to int Primary key. Silnik InnoDB
wookieb
Wrzuć prosze explain z zapytania
  1. EXPLAIN twoj_select

oraz schematy tabel user,vote
  1. SHOW CREATE TABLE `user`;
  2. SHOW CREATE TABLE `vote`';
snapshot
Dla poprzenich przykładów zmieniałem nazwy tabeli, żeby można było się połapać. Teraz pozwolę sobie zostawić oryginały.
  1. EXPLAIN SELECT COUNT(DISTINCT s.idartist) FROM on_air o INNER JOIN song s USING(idsong) WHERE o.idradio = 5

Kod
+----+-------------+-------+--------+------------------------------------------------+---------------------+---------+----------------+-------+-------+
| id | select_type | table | type   | possible_keys                                  | key                 | key_len | ref            | rows  | Extra |
+----+-------------+-------+--------+------------------------------------------------+---------------------+---------+----------------+-------+-------
|  1 | SIMPLE      | o     | ref    | fk_Onair_Radio1_idx,fk_Onair_Song1_idx,idradio | fk_Onair_Radio1_idx | 1       | const          | 49470 |       |
|  1 | SIMPLE      | s     | eq_ref | PRIMARY                                        | PRIMARY             | 3       | radio.o.idsong |     1 |       |
+----+-------------+-------+--------+------------------------------------------------+---------------------+---------+----------------+-------+-------+
2 rows in set (0.14 sec)

  1. CREATE TABLE `song` (
  2. `idsong` mediumint(8) UNSIGNED NOT NULL AUTO_INCREMENT,
  3. `title` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
  4. `redirect` mediumint(8) UNSIGNED DEFAULT NULL,
  5. `img_small` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  6. `img_big` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  7. `description` mediumblob,
  8. `lyric` mediumblob,
  9. `youtube` varchar(33) COLLATE utf8_unicode_ci DEFAULT NULL,
  10. `last_data_check` date NOT NULL,
  11. `idartist` mediumint(8) UNSIGNED NOT NULL,
  12. `slug` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
  13. PRIMARY KEY (`idsong`),
  14. UNIQUE KEY `un_Song_title_idArtist_idx` (`title`,`idartist`),
  15. UNIQUE KEY `IN_Song_slug_idx` (`slug`),
  16. KEY `fk_Song_Artist_idx` (`idartist`),
  17. KEY `reditect_idx` (`redirect`),
  18. CONSTRAINT `song_idartist_artist_idartist` FOREIGN KEY (`idartist`) REFERENCES `artist` (`idartist`) ON DELETE CASCADE ON UPDATE CASCADE,
  19. CONSTRAINT `song_redirect_song_idsong` FOREIGN KEY (`redirect`) REFERENCES `song` (`idsong`) ON DELETE SET NULL ON UPDATE SET NULL
  20. ) ENGINE=InnoDB AUTO_INCREMENT=25692 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci

  1. CREATE TABLE `on_air` (
  2. `idonair` mediumint(8) UNSIGNED NOT NULL AUTO_INCREMENT,
  3. `time` datetime NOT NULL,
  4. `idradio` tinyint(3) UNSIGNED NOT NULL,
  5. `idsong` mediumint(8) UNSIGNED NOT NULL,
  6. PRIMARY KEY (`idonair`),
  7. KEY `fk_Onair_Radio1_idx` (`idradio`),
  8. KEY `fk_Onair_Song1_idx` (`idsong`),
  9. KEY `idradio` (`idradio`,`idsong`),
  10. CONSTRAINT `on_air_idradio_radio_idradio` FOREIGN KEY (`idradio`) REFERENCES `radio` (`idradio`) ON DELETE CASCADE ON UPDATE CASCADE,
  11. CONSTRAINT `on_air_idsong_song_idsong` FOREIGN KEY (`idsong`) REFERENCES `song` (`idsong`) ON DELETE CASCADE ON UPDATE CASCADE
  12. ) ENGINE=InnoDB AUTO_INCREMENT=639365 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2024 Invision Power Services, Inc.