Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> Zliczanie unikalnych wartości, Optymalizacja
snapshot
post
Post #1





Grupa: Zarejestrowani
Postów: 96
Pomógł: 6
Dołączył: 22.08.2007
Skąd: Wrocław

Ostrzeżenie: (0%)
-----


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? (IMG:style_emoticons/default/smile.gif)
Go to the top of the page
+Quote Post
nospor
post
Post #2





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




a masz założony index na type?
Go to the top of the page
+Quote Post
Crozin
post
Post #3





Grupa: Zarejestrowani
Postów: 6 476
Pomógł: 1306
Dołączył: 6.08.2006
Skąd: Kraków

Ostrzeżenie: (0%)
-----


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.

Ten post edytował Crozin 24.05.2011, 10:52:14
Go to the top of the page
+Quote Post
wookieb
post
Post #4





Grupa: Moderatorzy
Postów: 8 989
Pomógł: 1550
Dołączył: 8.08.2008
Skąd: Słupsk/Gdańsk




Jak już to na type, user (2 kolumny w jednym indeksie)
Go to the top of the page
+Quote Post
snapshot
post
Post #5





Grupa: Zarejestrowani
Postów: 96
Pomógł: 6
Dołączył: 22.08.2007
Skąd: Wrocław

Ostrzeżenie: (0%)
-----


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...

Ten post edytował snapshot 24.05.2011, 11:36:50
Go to the top of the page
+Quote Post
wookieb
post
Post #6





Grupa: Moderatorzy
Postów: 8 989
Pomógł: 1550
Dołączył: 8.08.2008
Skąd: Słupsk/Gdańsk




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.
Go to the top of the page
+Quote Post
snapshot
post
Post #7





Grupa: Zarejestrowani
Postów: 96
Pomógł: 6
Dołączył: 22.08.2007
Skąd: Wrocław

Ostrzeżenie: (0%)
-----


Kolumna user w tabli user to int Primary key. Silnik InnoDB
Go to the top of the page
+Quote Post
wookieb
post
Post #8





Grupa: Moderatorzy
Postów: 8 989
Pomógł: 1550
Dołączył: 8.08.2008
Skąd: Słupsk/Gdańsk




Wrzuć prosze explain z zapytania
  1. EXPLAIN twoj_select

oraz schematy tabel user,vote
  1. SHOW CREATE TABLE `user`;
  2. SHOW CREATE TABLE `vote`';
Go to the top of the page
+Quote Post
snapshot
post
Post #9





Grupa: Zarejestrowani
Postów: 96
Pomógł: 6
Dołączył: 22.08.2007
Skąd: Wrocław

Ostrzeżenie: (0%)
-----


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
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 22.08.2025 - 17:39