Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> MySQL z dużą ilością danych
trifek
post 2.10.2015, 12:21:29
Post #1





Grupa: Zarejestrowani
Postów: 340
Pomógł: 0
Dołączył: 28.09.2015

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


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?
Go to the top of the page
+Quote Post
2 Stron V   1 2 >  
Start new topic
Odpowiedzi (1 - 19)
Pyton_000
post 2.10.2015, 12:38:53
Post #2





Grupa: Zarejestrowani
Postów: 8 068
Pomógł: 1414
Dołączył: 26.10.2005

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


Chcesz powiedzieć że tabele z kategoriami zajmują 1,5GB questionmark.gif To ile ty tam tego masz? 150mln ?
Go to the top of the page
+Quote Post
trifek
post 2.10.2015, 12:44:09
Post #3





Grupa: Zarejestrowani
Postów: 340
Pomógł: 0
Dołączył: 28.09.2015

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


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ć :/
Go to the top of the page
+Quote Post
markuz
post 2.10.2015, 12:49:20
Post #4





Grupa: Zarejestrowani
Postów: 1 240
Pomógł: 278
Dołączył: 11.03.2008

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


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


--------------------
Go to the top of the page
+Quote Post
KsaR
post 2.10.2015, 12:52:36
Post #5





Grupa: Zarejestrowani
Postów: 520
Pomógł: 102
Dołączył: 15.07.2014
Skąd: NULL

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


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

Ten post edytował KsaR 2.10.2015, 12:56:18


--------------------
Go to the top of the page
+Quote Post
trifek
post 2.10.2015, 12:56:40
Post #6





Grupa: Zarejestrowani
Postów: 340
Pomógł: 0
Dołączył: 28.09.2015

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


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?
Go to the top of the page
+Quote Post
KsaR
post 2.10.2015, 12:58:31
Post #7





Grupa: Zarejestrowani
Postów: 520
Pomógł: 102
Dołączył: 15.07.2014
Skąd: NULL

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


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.

Ten post edytował KsaR 2.10.2015, 13:01:00


--------------------
Go to the top of the page
+Quote Post
trifek
post 2.10.2015, 13:01:02
Post #8





Grupa: Zarejestrowani
Postów: 340
Pomógł: 0
Dołączył: 28.09.2015

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


  1.  
  2. ALTER TABLE `kategorie ` CHANGE `id ` `ADD PRIMARY KEY (`id`),`



takie coś?
Go to the top of the page
+Quote Post
Pyton_000
post 2.10.2015, 13:03:39
Post #9





Grupa: Zarejestrowani
Postów: 8 068
Pomógł: 1414
Dołączył: 26.10.2005

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


Wejdź sobie do PMA do Struktury i pod strukturą masz "Index" i tam możesz zmieniać, tak samo w strukturze możesz edytować
Go to the top of the page
+Quote Post
trifek
post 2.10.2015, 13:05:54
Post #10





Grupa: Zarejestrowani
Postów: 340
Pomógł: 0
Dołączył: 28.09.2015

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


zrobił coś takiego: ALTER TABLE `kategorie` ADD INDEX( `id`); to jest OK?
Go to the top of the page
+Quote Post
nospor
post 2.10.2015, 13:09:06
Post #11





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




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


--------------------

"Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista
"Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer

Go to the top of the page
+Quote Post
trifek
post 2.10.2015, 13:22:52
Post #12





Grupa: Zarejestrowani
Postów: 340
Pomógł: 0
Dołączył: 28.09.2015

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


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
Go to the top of the page
+Quote Post
nospor
post 2.10.2015, 13:25:11
Post #13





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




Juz samo ORDER by RAND() przy paru milionach rekordow jest w stanie zamulic baze totalnie niezaleznie od indeksow.


--------------------

"Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista
"Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer

Go to the top of the page
+Quote Post
trifek
post 2.10.2015, 13:27:55
Post #14





Grupa: Zarejestrowani
Postów: 340
Pomógł: 0
Dołączył: 28.09.2015

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


A jak takie losowanie lepiej rozwiązać?
Go to the top of the page
+Quote Post
nospor
post 2.10.2015, 13:31:49
Post #15





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




google -> losowanie mysql

Jeden z wynikow
http://blog.vokiel.com/mysql-rand-jak-pobrac-losowe-wiersze/


--------------------

"Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista
"Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer

Go to the top of the page
+Quote Post
trifek
post 2.10.2015, 13:35:00
Post #16





Grupa: Zarejestrowani
Postów: 340
Pomógł: 0
Dołączył: 28.09.2015

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


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
Go to the top of the page
+Quote Post
nospor
post 2.10.2015, 13:39:01
Post #17





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




Podalem ci linka, gdzie masz alternatywy. Autor opisal kazdą z nich. wybierz sobie.


--------------------

"Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista
"Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer

Go to the top of the page
+Quote Post
trifek
post 3.10.2015, 11:43:30
Post #18





Grupa: Zarejestrowani
Postów: 340
Pomógł: 0
Dołączył: 28.09.2015

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




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ć?

Ten post edytował trifek 3.10.2015, 11:43:43
Go to the top of the page
+Quote Post
Pyton_000
post 3.10.2015, 13:23:00
Post #19





Grupa: Zarejestrowani
Postów: 8 068
Pomógł: 1414
Dołączył: 26.10.2005

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


Nadal używasz RAND()
Go to the top of the page
+Quote Post
trifek
post 3.10.2015, 13:33:54
Post #20





Grupa: Zarejestrowani
Postów: 340
Pomógł: 0
Dołączył: 28.09.2015

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


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"?

Ten post edytował trifek 3.10.2015, 13:38:39
Go to the top of the page
+Quote Post

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

 



RSS Wersja Lo-Fi Aktualny czas: 14.08.2025 - 03:40