Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: MySQL z dużą ilością danych
Forum PHP.pl > Forum > Bazy danych > MySQL
trifek
Witam serdecznie,
Mam taką tabelkę:

  1. CREATE TABLE IF NOT EXISTS `kategorie` (
  2. `id` bigint(20) UNSIGNED NOT NULL,
  3. `tytul` varchar(85) COLLATE utf8_unicode_ci DEFAULT NULL,
  4. `domena_url` varchar(100) COLLATE utf8_unicode_ci DEFAULT NULL,
  5. `enable` int(11) NOT NULL DEFAULT '0',
  6. `level` int(11) NOT NULL DEFAULT '0',
  7. `parent_id` int(11) NOT NULL DEFAULT '0'
  8. ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
  9.  
  10. --
  11. -- Indeksy dla zrzutów tabel
  12. --
  13.  
  14. --
  15. -- Indexes for table `cms_kategorie`
  16. --
  17. ALTER TABLE `cms_kategorie`
  18. ADD PRIMARY KEY (`bf_id`),
  19. ADD UNIQUE KEY `bf_id` (`bf_id`),
  20. ADD KEY `bf_id_2` (`bf_id`);
  21.  
  22. --
  23. -- AUTO_INCREMENT for dumped tables
  24. --
  25.  
  26. --
  27. -- AUTO_INCREMENT dla tabeli `cms_kategorie`
  28. --
  29. ALTER TABLE `cms_kategorie`
  30. MODIFY `bf_id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT;



Mój serwer: http://www.online.net/en/dedicated-server/dedibox-xc - z hdd sata3
Tabela ma 1.5GB.


Mój /my.cnf:
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
user=mysql
symbolic-links=0
max_connections=600
max_user_connections=400
wait_timeout=30
interactive_timeout=50
long_query_time=5
#log-queries-not-using-indexes
#log-slow-queries=/var/log/mysql/log-slow-queries.log

#innodb_use_native_aio = 0
innodb_file_per_table

[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid

thread_cache_size = 256
table_cache = 1024
key_buffer = 64M
sort_buffer_size = 256K
read_buffer_size = 256K
read_rnd_buffer_size = 256K
max_allowed_packet = 1M
tmp_table_size=64M


Niestety strony ładują się dość długo. Czy da się to jakoś przyśpieszyć?
Czy raczej to problem serwera?
Pyton_000
Chcesz powiedzieć że tabele z kategoriami zajmują 1,5GB questionmark.gif To ile ty tam tego masz? 150mln ?
trifek
W tej chwili nie mam dostępu do tej bazy, mam stary backup.
1,285,751 rekordów zajmowało 203.8 MB - teraz baza ma ok 1,3GB - ale może "utyć" do tych 1,5GB i zastanawiam się czy trzeba ten serwer zmieniać,czy wystarczy coś z konfiguracją pokombinować :/
markuz
Założ indeksy na id i parent_id jak jeszcze tego nie zrobiłeś - Baza się powiększy o kilkadziesiąt % ale będzie szybciej działać.
KsaR
ALTER TABLE `cms_kategorie`
ADD PRIMARY KEY (`bf_id`),
ADD UNIQUE KEY `bf_id` (`bf_id`),
ADD KEY `bf_id_2` (`bf_id`);
Wedlug mnie - bezsens, tylko zajmujesz miejsce i opozniasz a nie przyszybszasz.
Zostaw 1 klucz, np. PRIMARY KEY. Inne pokasuj.

bigint zmien na mediumint UNSIGNED (dzieki jej mozesz max. 16777215 id).
int UNSIGNED ma max. 4294967295 ale juz wazy 4 zamiast 3 bajtów ;p
trifek
Są klucze smile.gif

Cytat(KsaR @ 2.10.2015, 13:52:36 ) *
ALTER TABLE `cms_kategorie`
ADD PRIMARY KEY (`bf_id`),
ADD UNIQUE KEY `bf_id` (`bf_id`),
ADD KEY `bf_id_2` (`bf_id`);
Wedlug mnie - bezsens, tylko zajmujesz miejsce i opozniasz a nie przyszybszasz.
Zostaw 1 klucz, np. PRIMARY KEY. Inne pokasuj.

bigint zmien na mediumint UNSIGNED (dzieki jej mozesz max. 16777215 id).
int UNSIGNED ma max. 4294967295 ale juz wazy 4 zamiast 3 bajtów ;p



da się to jakoś zdjąć z poziomu phpmyadmin?
KsaR
Cytat(trifek @ 2.10.2015, 13:56:40 ) *
Są klucze smile.gif




da się to jakoś zdjąć z poziomu phpmyadmin?

  1. ALTER TABLE `kategorie` CHANGE `id` `id` mediumint UNSIGNED NOT NULL PRIMARY KEY

Reszte bys musial poogoglowac, np. Ta kasacje nadmiernych kluczy.
trifek
  1.  
  2. ALTER TABLE `kategorie ` CHANGE `id ` `ADD PRIMARY KEY (`id`),`



takie coś?
Pyton_000
Wejdź sobie do PMA do Struktury i pod strukturą masz "Index" i tam możesz zmieniać, tak samo w strukturze możesz edytować
trifek
zrobił coś takiego: ALTER TABLE `kategorie` ADD INDEX( `id`); to jest OK?
nospor
trifek napisal, ze strona mu muli. Nie napisal, ze to zapytanie mu muli a ze strona. A to duza roznica.
Spojrzcie na jego strukture drzewiastą, samo `parent_id` . No jak to niby ma dzialac szybko? Toż to najgorsza struktura jaką można mieć. I jeśli teraz aplikacja probuje pobierac jakieś drzewkowe dane czy cokolwiek, to logiczne ze muli.

Oczywiscie problem może też być w jakiś indeksach. No ale po co zgadywać? Dobrze by było, by trifek zdiagnozował ktore czesci kodu/zapytan dokladnie mulą.
trifek
dzięki za pomoc smile.gif

Tam nie ma nic nadzwyczajnego, wyświetlam dane na zasadzie:

  1.  
  2. $miasta = Array();
  3. $stmt = $db->prepare("select tytul, domena_url, id FROM kategorie1 WHERE enable= 1 ORDER by RAND() ASC limit 50;");
  4. $stmt->execute();
  5. foreach ($stmt as $rowX) {
  6. array_push($miasta, $rowX['tytul']);
  7. }
  8. $stmt->closeCursor();
  9.  
  10. $produkty = Array();
  11. $stmt = $db->prepare("select tytul, domena_url, id FROM kategorie2 WHERE enable= 1 ORDER by RAND() ASC limit 50;");
  12. $stmt->execute();
  13. foreach ($stmt as $rowX) {
  14. array_push($produkty, $rowX['tytul']);
  15. }
  16. $stmt->closeCursor();
  17.  
  18. $res = array();
  19. foreach($miasta as $val) {
  20. $nazwa_miasta = baza_odczyt($val .' ' . array_shift($produkty));
  21. echo "<a href='".$portal_url."' title='".$nazwa_miasta."'>".$nazwa_miasta."</a>, ";
  22. }
  23.  
  24.  



tam oczywiście są jakieś inne "końcówki" tego zaytania.... np nie ma rand a jest where parent_id = ..... itp.

Jest to generalnie wyświetlanie danych z tej bazy
nospor
Juz samo ORDER by RAND() przy paru milionach rekordow jest w stanie zamulic baze totalnie niezaleznie od indeksow.
trifek
A jak takie losowanie lepiej rozwiązać?
nospor
google -> losowanie mysql

Jeden z wynikow
http://blog.vokiel.com/mysql-rand-jak-pobrac-losowe-wiersze/
trifek
Dziękuję bardzo smile.gif

Myślisz o tej procedurze:

  1. DELIMITER $$
  2. DROP PROCEDURE IF EXISTS getRandomRecords$$
  3. CREATE PROCEDURE getRandomRecords(IN cnt INT)
  4.  
  5. BEGIN
  6. DROP TEMPORARY TABLE IF EXISTS randomRecords;
  7. CREATE TEMPORARY TABLE randomRecords ( `rand_id` INT, `sub` CHAR(255) );
  8.  
  9. loop_random: LOOP
  10. IF cnt < 1 THEN
  11. LEAVE loop_random;
  12. END IF;
  13.  
  14. INSERT INTO randomRecords
  15. SELECT r1.id, r1.sub FROM `keys` AS r1 JOIN
  16. (SELECT (RAND() *
  17. (SELECT MAX(id) FROM `keys`)) AS id) AS r2
  18. WHERE r1.id >= r2.id ORDER BY r1.id ASC LIMIT 1;
  19. SET cnt = cnt - 1;
  20. END LOOP loop_random;
  21.  
  22. SELECT * FROM randomRecords;
  23. END$$
  24. DELIMITER ;


questionmark.gifsmile.gif
nospor
Podalem ci linka, gdzie masz alternatywy. Autor opisal kazdą z nich. wybierz sobie.
trifek


Faktycznie wymiana zapytania pomogła smile.gif

Zrobiłem takie zapytanie:
SELECT tytul, domena_url FROM kategorie WHERE enable = 1 and RAND()<(SELECT ((50/COUNT(*))*50) FROM kategorie) ORDER BY RAND() LIMIT 50 ;

I skrypt działa jakieś 40% szybciej, jednak jeszcze wolno... Ma ktoś może jakiś pomysł jak to przyśpieszyć?
Pyton_000
Nadal używasz RAND()
trifek
takie coś znalazłem w przykładzie... da się to jakoś zastąpić?
W tym linku ta procedura wygląda fajnie, tylko nie potrafię jej zaadaptować sad.gif

Wiesz może czy poprawnie ją "przerobiłem"?
Pyton_000
tu masz kilka przykładów jeszcze

http://pastebin.com/WPmrdL9f
trifek
pod tym linkiem nic nie ma....sad.gif Są jakieś prywatne dane dostępne po logowaniu, tak?
Pyton_000
ah wybacz, już poprawiłem uprawnienia.
trifek
Dziękuję bardzo smile.gif
U mnie najszybciej działa ten wariant zapytania:
  1. SELECT t.* FROM (SELECT ROUND(RAND() * (SELECT MAX(bf_id) FROM kategorie WHERE enable = 1 AND domena_url <>'')) num, @num:=@num+1 FROM ( SELECT @num:=0) AS a, kategorie LIMIT 50) AS b, kategorie AS t WHERE enable = 1 AND domena_url <>'' AND b.num = t.bf_id


Jednak nie zawsze losuje mi te 50 rekordów, a często 39/44... Dlaczego?

To zapytanie jest dużo szybsze niż to moje początkowe smile.gif
Pyton_000
Zapewne dlatego że to zapytanie działa optymalnie jeśli nie ma dziur w ID, a u Ciebie zapewne są.
trifek
Dokładnie, u mnie są dziury... sad.gif
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-2025 Invision Power Services, Inc.