Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

2 Stron V   1 2 >  
Reply to this topicStart new topic
> przepełniająca tabela bazy danych
maksik
post 17.12.2013, 09:30:06
Post #1





Grupa: Zarejestrowani
Postów: 206
Pomógł: 0
Dołączył: 26.09.2012

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


Witam

Mam dwie tabele powiedzmy że to są X, Y
X- znajdują się w tej tabeli artykuły do oglądania przez użytkowników, po kolei wyświetla użytkownikowi każdy rekord, gdy użytkownik obejży artykuł zapisuje się do bazy Y numer id artykułu i następnie gdy użytkownik przechodzi do następnego artykułu, wtedy skrypt sprawdza w tabeli Y który artykuł już się wyświetlił (aby nie oglądał tego samego po kolei) i pobiera z tabeli X pierwszy artykuł do wyświetlenia którego id nie jest zapisane w tabeli Y i tak wkółko.


Problem polega na tym że tabela Y się przepełnia tzn gdy uzyska kilkadziesiąt tysiecy rekordków należy ją czyścić ponieważ skrypt wyświetlania wolno zaczyna wczytywać. Jest możliwość innego rozwiązania, lub można temu jakoś zaradzić aby nie trzeba było tego czyścić?
Go to the top of the page
+Quote Post
toffiak
post 17.12.2013, 09:35:06
Post #2





Grupa: Zarejestrowani
Postów: 395
Pomógł: 80
Dołączył: 24.08.2009

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


Kilkadziesiąt tysięcy rekordów to tyle co nic dla każdej bazy danych, problem leży prawdopodobie gdzie indziej.


--------------------
Go to the top of the page
+Quote Post
maksik
post 17.12.2013, 09:38:15
Post #3





Grupa: Zarejestrowani
Postów: 206
Pomógł: 0
Dołączył: 26.09.2012

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


a samo to, że skrypt przed wyświetleniem wyniku za każdym razem przeszukuje te ogromną tabele z id było już wyświetlane? to też nie ma wpływu?
Go to the top of the page
+Quote Post
phpion
post 17.12.2013, 09:38:17
Post #4





Grupa: Moderatorzy
Postów: 6 072
Pomógł: 861
Dołączył: 10.12.2003
Skąd: Dąbrowa Górnicza




Problem pewnie leży w braku/nieprawidłowych indeksach lub w zapytaniu pobierającym dane z tabeli Y. Bez struktury tabeli i zapytania nic nie poradzimy.

W sumie: pewnie możesz to oprzeć na 1 zapytaniu z wykorzystaniem NOT EXISTS.
Go to the top of the page
+Quote Post
maksik
post 17.12.2013, 09:58:08
Post #5





Grupa: Zarejestrowani
Postów: 206
Pomógł: 0
Dołączył: 26.09.2012

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


samo zapytanie pobierające artykuł i sprawdzające czy nie był on już wcześniej wyświetlany, możecie określić czy powinien on być inaczej skonstruowany i to on może powodować spowalnianie przy dużej ilości rekordów?

  1. $query = mysql_query("SELECT X.id, nazwa, wpis FROM X WHERE NOT EXISTS (Select id FROM Y WHERE X.id = Y.id and login = '".$login."') LIMIT 0,1 ");
  2.  



struktura tabeli X

  1. CREATE TABLE IF NOT EXISTS `X` (
  2. `id` int(11) NOT NULL AUTO_INCREMENT,
  3. `nazwa` varchar(99) CHARACTER SET latin2 DEFAULT NULL,
  4. `limit` int(11) DEFAULT NULL,
  5. `login` varchar(30) CHARACTER SET latin2 DEFAULT NULL,
  6. `date` varchar(50) CHARACTER SET latin2 DEFAULT NULL,
  7. `wpis` varchar(200) COLLATE utf8_polish_ci NOT NULL,
  8. `licznik` int(11) NOT NULL,
  9. PRIMARY KEY (`id`)
  10. ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci AUTO_INCREMENT=42815 ;



tabeli Y

  1. CREATE TABLE IF NOT EXISTS `Y` (
  2. `idY` int(11) NOT NULL AUTO_INCREMENT,
  3. `id` varchar(50) CHARACTER SET latin2 DEFAULT NULL,
  4. `login` varchar(30) CHARACTER SET latin2 DEFAULT NULL,
  5. `date` varchar(50) CHARACTER SET latin2 DEFAULT NULL,
  6. `akcja` int(2) NOT NULL,
  7. PRIMARY KEY (`idY`),
  8. KEY `Indeks6` (`login`)
  9. ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci AUTO_INCREMENT=2605241 ;


Ten post edytował maksik 17.12.2013, 10:06:37
Go to the top of the page
+Quote Post
phpion
post 17.12.2013, 10:10:43
Post #6





Grupa: Moderatorzy
Postów: 6 072
Pomógł: 861
Dołączył: 10.12.2003
Skąd: Dąbrowa Górnicza




Cytat
WHERE X.id = Y.id and login = '".$login."'

Zmień typ kolumny Y.id na taki by odpowiadał X.id. Aktualnie masz varchar vs integer, czyli podczas przeszukiwania danych następuje rzutowanie wartości. Dodatkowo załóż jeden indeks na obu kolumnach (id oraz login). Aktualnie masz tylko na login. Powinno znacząco pomóc.
Go to the top of the page
+Quote Post
maksik
post 17.12.2013, 10:21:43
Post #7





Grupa: Zarejestrowani
Postów: 206
Pomógł: 0
Dołączył: 26.09.2012

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


czyli index dla tabeli Y powinny wyglądać tak?

  1. PRIMARY KEY `Indeks6` (`idY`),
  2. KEY `Indeks6` (`login`)


Ten post edytował maksik 17.12.2013, 10:21:58
Go to the top of the page
+Quote Post
phpion
post 17.12.2013, 10:28:29
Post #8





Grupa: Moderatorzy
Postów: 6 072
Pomógł: 861
Dołączył: 10.12.2003
Skąd: Dąbrowa Górnicza




Nie, napisałem Ci pogrubioną czcionką: jeden indeks na obu kolumnach. Wykonaj to:
  1. ALTER TABLE `Y` CHANGE COLUMN `id` `id` INT(11) NOT NULL
  2. , DROP INDEX `Indeks6`
  3. , ADD INDEX `Indeks6` (`id` ASC, `login` ASC) ;

Sprawdź czy zapytanie przyspieszyło. Jeśli nie - wklej wyniki:
  1. EXPLAIN SELECT ...

gdzie ... to całe Twoje zapytanie.
Go to the top of the page
+Quote Post
nospor
post 17.12.2013, 10:40:01
Post #9





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




Cytat
X- znajdują się w tej tabeli artykuły do oglądania przez użytkowników, po kolei wyświetla użytkownikowi każdy rekord, gdy użytkownik obejży artykuł zapisuje się do bazy Y numer id artykułu i następnie gdy użytkownik przechodzi do następnego artykułu, wtedy skrypt sprawdza w tabeli Y który artykuł już się wyświetlił (aby nie oglądał tego samego po kolei) i pobiera z tabeli X pierwszy artykuł do wyświetlenia którego id nie jest zapisane w tabeli Y i tak wkółko.
Skoro artykuly wyswietlane są pokolei, to po co zapisywac calą sciezke jaką przeszeedl? Zapisuj tylko ostatnio obejrzany art, a nastepnie wyswietlaj art z wiekszym ID od ostatnio obejrzanego.

Ponadto w tabelach powinien byc zapisywane ID uzytkownika a nie jego login.


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

"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
maksik
post 17.12.2013, 11:09:36
Post #10





Grupa: Zarejestrowani
Postów: 206
Pomógł: 0
Dołączył: 26.09.2012

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


Cytat(nospor @ 17.12.2013, 10:40:01 ) *
Skoro artykuly wyswietlane są pokolei, to po co zapisywac calą sciezke jaką przeszeedl? Zapisuj tylko ostatnio obejrzany art, a nastepnie wyswietlaj art z wiekszym ID od ostatnio obejrzanego.

Ponadto w tabelach powinien byc zapisywane ID uzytkownika a nie jego login.




to by było dobre rozwiązanie jednak ten układ "ilościowy" jest istotny dla zliczania statystyki dniowej dla poszczególnego użytkownika
Go to the top of the page
+Quote Post
phpion
post 17.12.2013, 11:17:24
Post #11





Grupa: Moderatorzy
Postów: 6 072
Pomógł: 861
Dołączył: 10.12.2003
Skąd: Dąbrowa Górnicza




Dałeś "Pomógł" - rozumiem, że zapytanie przyspieszyło smile.gif
Go to the top of the page
+Quote Post
maksik
post 17.12.2013, 11:25:45
Post #12





Grupa: Zarejestrowani
Postów: 206
Pomógł: 0
Dołączył: 26.09.2012

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


Wpisując zapytanie ze starymi indeksami
  1. Showing rows 0 - 0 (1 total, Wykonanie zapytania trwało 0.3033 sekund(y))


z tymi które zasugerowałeś
  1. Showing rows 0 - 0 (1 total, Wykonanie zapytania trwało 0.4003 sekund(y))

lub
  1. Showing rows 0 - 0 (1 total, Wykonanie zapytania trwało 0.0003 sekund(y))


Pomogło bardzo, ale nie wiem dlaczego chociaż na kilkadziesiąt prób rzadko trwa to 0.4 s , a raz ułamek sekundy!

Mam jeszcze pytanie do ciebie ponieważ kiedyś miałem problem u usługodawcy vps który notował zbyt duże obciążenia kodu php, zawsze pomagało gdy oczyścilem tabele Y czy te indeksy mogły być tego przyczyną?

Ten post edytował maksik 17.12.2013, 11:30:02
Go to the top of the page
+Quote Post
phpion
post 17.12.2013, 11:43:25
Post #13





Grupa: Moderatorzy
Postów: 6 072
Pomógł: 861
Dołączył: 10.12.2003
Skąd: Dąbrowa Górnicza




Tak, jeżeli uruchamiałeś zapytania trwające stosunkowo długo to obciążałeś bazę danych. Im szybciej wykonywane zapytania tym mniejszy narzut. Kilkadziesiąt tysięcy rekordów to dla bazy pierdnięcie wink.gif o ile mają odpowiednie typy danych, indeksy.
Go to the top of the page
+Quote Post
CuteOne
post 17.12.2013, 11:48:19
Post #14





Grupa: Zarejestrowani
Postów: 2 958
Pomógł: 574
Dołączył: 23.09.2008
Skąd: wiesz, że tu jestem?

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


Rozwiązanie to mix odpowiedzi nospora i phpiona. Stwórz tabelę archiwalną, w której będziesz jedynie dopisywał kolejne rekordy oraz tabelę taką jak zaproponował nospor. W drugiej tabeli będzie tylko jeden rekord na użytkownika co powinno znacząco pomóc w odczycie danych
Go to the top of the page
+Quote Post
maksik
post 19.12.2013, 22:32:04
Post #15





Grupa: Zarejestrowani
Postów: 206
Pomógł: 0
Dołączył: 26.09.2012

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


jednak nic to nie dało... przeciążenie się pojawiło, a sposób nospora się nie sprawdzi w moim przypadku ponieważ zapytania do "większej" tabeli z bazy danych również muszą być wywoływane za każdym artykułem do liczników także chyba nie ma sensu oddzielenia tego zapytania w innej tabeli? może te zapytanie powoduje problem skoro indexowanie jest wporządku? a czy tabela X nie musi mieć również jakiś indexów?
Go to the top of the page
+Quote Post
CuteOne
post 20.12.2013, 08:45:11
Post #16





Grupa: Zarejestrowani
Postów: 2 958
Pomógł: 574
Dołączył: 23.09.2008
Skąd: wiesz, że tu jestem?

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


Zamiast dodać kolumnę "licznik" do tabeli z danymi artykułu, zliczasz ilość wejść COUNT'em?
Go to the top of the page
+Quote Post
maksik
post 20.12.2013, 09:32:26
Post #17





Grupa: Zarejestrowani
Postów: 206
Pomógł: 0
Dołączył: 26.09.2012

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


dokładnie tak, COUNT może wywoływać nadmierne obciążenia?
Go to the top of the page
+Quote Post
nospor
post 20.12.2013, 09:39:20
Post #18





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




No ale po co ci tu count?? W mojej wersji miales zapisywac tylko ID ostatnio ogladanego rekordu dla danego usera i tu zaden count nie jest potrzebny.
W mixie zas, gdzie miales dodac tabele archiwalną to tam jest tez tylko INSERT wiec COUNT nadal nigdzie nie jest potrzebny.
W mixie masz lepsza sytuacje, bo do duzej tabeli idziesz tylko raz wraz z insertem a nie jak teraz dwa razy do odczytu ostatniego id i do inserta.

Zas co do indeksu w X to chyba juz nie trzeba, bo do arta przeciez odwolujesz sie przez ID a ono jest kluczem glownym, czyz nie?


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

"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
maksik
post 20.12.2013, 09:46:02
Post #19





Grupa: Zarejestrowani
Postów: 206
Pomógł: 0
Dołączył: 26.09.2012

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


tak COUNT używam do zliczania artykułów obejżanych przez użytkownika i następnie do ustawień statystyki dla każdego z użytkownika która jest wyświetlana zawsze po każdym obejżeniu dlatego jeżeli powoduje przeciążenie to w tabeli archiwalnej chyba te obciążenie będzie dalej występować?
Go to the top of the page
+Quote Post
nospor
post 20.12.2013, 09:51:18
Post #20





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




Ciezko cos ogarnac z tych opisow twoich....
COUNT samo w sobie jest bardzo szybkie nawet dla bardzo duzej liczby rekordow.

1) Sprawdz czas wszystkich zapytan jakie generujesz, to bedziesz wiedzial ktore dokladnie ci muli. Tu nie ma co zgadywac.
2) Powinienes napisac poprawnie swoją tabele. Pisalem ci juz o tym wczesniej, przypomne jeszcze raz:
`login` varchar(30) CHARACTER SET latin2 DEFAULT NULL,
`date` varchar(50) CHARACTER SET latin2 DEFAULT NULL,
`akcja` int(2) NOT NULL,

Nie powinno byc pola login, tylko id usera
Data powinna być polem datowym a nie tekstem. Wkoncu data to data.
akcja powinna byc tinyint a nie int, bo zakladam ze tam są male liczby.


To tak na poczatek.


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

"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

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: 24.06.2025 - 00:36