php-resource



Zurück   PHP-Scripte PHP-Tutorials PHP-Jobs und vieles mehr > Entwicklung > SQL / Datenbanken
 

Login

 
eingeloggt bleiben
star Jetzt registrieren   star Passwort vergessen
 

 

 


SQL / Datenbanken Probleme mit SQL? Hier könnt ihr eure Fragen zu SQL (MySQL, PostgreSQL, MS-SQL und andere ANSI-SQL Server) los werden.

Antwort
 
LinkBack Themen-Optionen Thema bewerten
  #1 (permalink)  
Alt 27-04-2009, 01:02
martinm79
 Registrierter Benutzer
Links : Onlinestatus : martinm79 ist offline
Registriert seit: Jan 2004
Ort: Deutschland
Beiträge: 744
martinm79 ist zur Zeit noch ein unbeschriebenes Blatt
Standard SQL Abfrage optimieren

Hallo,

mich würde mal interessieren, ob man eine Abfrage noch optimieren kann.
Und wenn ja, was ich noch verbessern kann?


Bei jedem Seitenaufruf prüft diese, ob der User eine neue Nachricht hat.
In der Nachrichtentabelle befinden sich zurzeit ca. 300000 Einträge.
Die Abfrage dauert "im Schnitt" 0.02 Sekunden.

PHP-Code:
SELECT
    COUNT
(*) a
FROM
    prefix_nachrichten
WHERE
    user_id_ein 
'%d'
AND
    
del_ein 0
AND
    
datum_gelesen IS NULL 

Bei einer Abfrage mit Explain kommt das raus:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE prefix_nachrichten ref prefix_nachrichten_FKIndex1,del_ein prefix_nachrichten_FKIndex1 4 const 2863 Using where

Das ist der Aufbau der Tabelle.
PHP-Code:
CREATE TABLE prefix_nachrichten (
  
nachrichten_id INTEGER UNSIGNED NOT NULL,
  
ordner_id INTEGER UNSIGNED NOT NULL DEFAULT 0,
  
user_id_ein INTEGER UNSIGNED NOT NULL DEFAULT 0,
  
user_id_aus INTEGER UNSIGNED NOT NULL DEFAULT 0,
  
antwort_id INTEGER UNSIGNED NOT NULL DEFAULT 0,
  
del_ein TINYINT(1UNSIGNED NOT NULL DEFAULT 0,
  
del_aus TINYINT(1UNSIGNED NOT NULL DEFAULT 0,
  
datum_del_ein DATETIME NULL,
  
datum_del_aus DATETIME NULL,
  
datum_gesendet DATETIME NULL,
  
datum_gelesen DATETIME NULL,
  
datum_beantwortet DATETIME NULL,
  
nachricht TEXT NULL,
  
PRIMARY KEY(nachrichten_id),
  
INDEX prefix_nachrichten_FKIndex1(user_id_ein),
  
INDEX prefix_nachrichten_FKIndex2(user_id_aus),
  
INDEX prefix_nachrichten_FKIndex3(ordner_id),
  
INDEX prefix_nachrichten_FKIndex4(del_ein)
); 
Ich frage mich, wie Xing oder andere Seiten sowas lösen. In deren Tabellen befinden sich doch mehrere Millionen Einträge.

Wie kann ich die Abfrage noch verbessern?
__________________
Gut geraten ist halb gewußt.
Mit Zitat antworten
  #2 (permalink)  
Alt 27-04-2009, 01:16
h3ll
 Registrierter Benutzer
Links : Onlinestatus : h3ll ist offline
Registriert seit: Mar 2008
Beiträge: 3.578
h3ll befindet sich auf einem aufstrebenden Ast
Standard

Mach mal ein EXPLAIN().

Hat damit nix zu tun, aber ich würd mich interessieren, warum du für del_ein und del_aus ein TINYINT verwendest? Wäre da nicht ENUM passender?
Mit Zitat antworten
  #3 (permalink)  
Alt 27-04-2009, 01:25
TBT
  Moderator
Links : Onlinestatus : TBT ist offline
Registriert seit: Sep 2002
Ort: Berlin
Beiträge: 2.787
TBT befindet sich auf einem aufstrebenden Ast
TBT eine Nachricht über ICQ schicken TBT eine Nachricht über AIM schicken TBT eine Nachricht über Yahoo! schicken
Standard

einen Index über alle 3 Felder aus der WHERE Bedingung
__________________
TBT

Die zwei wichtigsten Regeln für eine berufliche Karriere:
1. Verrate niemals alles was du weißt!


PHP 2 AllPatrizier II Browsergame
Mit Zitat antworten
  #4 (permalink)  
Alt 27-04-2009, 01:25
Benutzerbild von onemorenerd onemorenerd
  Moderator
Links : Onlinestatus : onemorenerd ist offline
Registriert seit: Mar 2005
Ort: Berlin
Beiträge: 9.471
onemorenerd wird schon bald berühmt werdenonemorenerd wird schon bald berühmt werden
Standard Re: SQL Abfrage optimieren

Zitat:
Original geschrieben von martinm79
Ich frage mich, wie Xing oder andere Seiten sowas lösen.
Na vielleicht in-/dekrementieren sie einfach einen Zähler im Userprofil wenn eine Nachricht eingeht bzw. gelesen wird. Meldet sich der User an, kann der Zähler zusammen mit dem Passwortvergleich aus der DB in die Session geholt werden.
Das heißt, wenn ein User gerade eingeloggt ist, muss der Zähler (auch) in seiner Session angepasst werden.

Ich weiß nicht wie es Xing oder andere machen. Aber so ginge es, wie du siehst, völlig ohne DB-Anfrage.

Geändert von onemorenerd (27-04-2009 um 01:27 Uhr)
Mit Zitat antworten
  #5 (permalink)  
Alt 27-04-2009, 01:45
martinm79
 Registrierter Benutzer
Links : Onlinestatus : martinm79 ist offline
Registriert seit: Jan 2004
Ort: Deutschland
Beiträge: 744
martinm79 ist zur Zeit noch ein unbeschriebenes Blatt
Standard

@h3ll
Ein
PHP-Code:
EXPLAIN SELECT
    COUNT
(*) a
FROM
    prefix_nachrichten
WHERE
    user_id_ein 
'1'
AND
    
del_ein 0
AND
    
datum_gelesen IS NULL 
habe ich schon gemacht. Das Ergebnis steht oben im Posting drinne.
Hat Tinyint nicht 1 Byte Speicherbedarf?
Ich guck mir das morgen nochmal an.

@TBT
Wie mache ich einen Index über alle 3 Felder aus der WHERE Bedingung ?

Wo ich den Index bei "del_ein" vorhin gesetzt habe, hat MYSQL knapp 27 Sekunden gebraucht und es war danach schon bisschen besser. Also davor dauerten die Abfragen noch länger als 0.02


@onemorenerd
Das mit dem zwischenspeichern in der Session habe ich mir zwar auch schon überlegt. Das würde mir aber nur was nützen bei der gesamten Nachrichtenanzahl. Trotzdem muß ich immer bei jedem Seitenaufruf mit einer kleinen Abfrage gucken ob eine neue Nachricht da ist.
__________________
Gut geraten ist halb gewußt.
Mit Zitat antworten
  #6 (permalink)  
Alt 27-04-2009, 01:58
h3ll
 Registrierter Benutzer
Links : Onlinestatus : h3ll ist offline
Registriert seit: Mar 2008
Beiträge: 3.578
h3ll befindet sich auf einem aufstrebenden Ast
Standard

Zitat:
Original geschrieben von martinm79
Hat Tinyint nicht 1 Byte Speicherbedarf?
Ja schon, aber wenn du nur 0 und 1 verwendest, hast du 254 weitere mögliche undefinierte Zustände. Ich sprech das nicht wegen der Leistung an, sondern nur der Logik wegen. Von der Leistung her ist es wahrscheinlich völlig egal.

Bei deinem EXPLAIN kann ich irgendwie überhaupt nichts erkennen. Kannst du das lesbar formatieren?

Geändert von h3ll (27-04-2009 um 02:01 Uhr)
Mit Zitat antworten
  #7 (permalink)  
Alt 27-04-2009, 02:32
martinm79
 Registrierter Benutzer
Links : Onlinestatus : martinm79 ist offline
Registriert seit: Jan 2004
Ort: Deutschland
Beiträge: 744
martinm79 ist zur Zeit noch ein unbeschriebenes Blatt
Standard

Habe das Ergebnis von Explain als Grafik im Angang.

Konnte es hier leider nicht besser darstellen.

Ja stimmt 0 und 1, das hätte ich auch in einer Spalte bekommen. Ich hätte aber auch eine timestamp Spalte mit 4 Byte nehmen sollen und nicht Datetime mit 8 Byte. Nächstes mal bin ich schlauer.


Leider komm ich mit dem Explain Ergebnis nicht weiter.
Angehängte Grafiken
Dateityp: gif unbenannt-1.gif (9,2 KB, 121x aufgerufen)
__________________
Gut geraten ist halb gewußt.
Mit Zitat antworten
  #8 (permalink)  
Alt 27-04-2009, 09:04
PHP-Desaster
 PHP Expert
Links : Onlinestatus : PHP-Desaster ist offline
Registriert seit: Mar 2006
Beiträge: 3.105
PHP-Desaster befindet sich auf einem aufstrebenden Ast
Standard

Schau doch mal im Manual nach. Dort steht zum Beispiel, dass der Typ const für eine solche Abfrage der bestmögliche Typ ist. Die Abfrage ist also schon gut.
Mit Zitat antworten
  #9 (permalink)  
Alt 27-04-2009, 12:26
Benutzerbild von onemorenerd onemorenerd
  Moderator
Links : Onlinestatus : onemorenerd ist offline
Registriert seit: Mar 2005
Ort: Berlin
Beiträge: 9.471
onemorenerd wird schon bald berühmt werdenonemorenerd wird schon bald berühmt werden
Standard

Zitat:
Original geschrieben von martinm79
@onemorenerd
Das mit dem zwischenspeichern in der Session habe ich mir zwar auch schon überlegt. Das würde mir aber nur was nützen bei der gesamten Nachrichtenanzahl. Trotzdem muß ich immer bei jedem Seitenaufruf mit einer kleinen Abfrage gucken ob eine neue Nachricht da ist.
Nein, nicht bei jedem Seitenaufruf sondern nur wenn eine neue Nachricht eingeht. Aber geh erstmal den üblichen Weg. Bis du die Größe von Xing erreichst, ist das völlig okay.
Mit Zitat antworten
  #10 (permalink)  
Alt 27-04-2009, 13:55
UzumakiNaruto
 Registrierter Benutzer
Links : Onlinestatus : UzumakiNaruto ist offline
Registriert seit: Nov 2004
Beiträge: 642
UzumakiNaruto befindet sich auf einem aufstrebenden Ast
Standard

user 234 schickt eine nachricht an user 2

die nachricht wird in der db gespeichert.
zusätzlich wird der nachrichtenzähler von user2 um eins hochgezählt.
ließt user 1 die nachricht wird er wieder runter gezählt.

das wäre die schnellste möglichkeit,

phpbb3 macht das genauso (wbb wohl auch) .. mit den posts und den pns.
__________________
Gruß
Uzu

private Homepage
Mit Zitat antworten
  #11 (permalink)  
Alt 27-04-2009, 13:56
UzumakiNaruto
 Registrierter Benutzer
Links : Onlinestatus : UzumakiNaruto ist offline
Registriert seit: Nov 2004
Beiträge: 642
UzumakiNaruto befindet sich auf einem aufstrebenden Ast
Standard

ich meinte natürlich wenn user 2 die nachricht ließt

und du musst immer überprüfen ob es neue nachrichten gibt .. bei jedem seitenaufruf .. da wirst du NIE drumrumkommen
__________________
Gruß
Uzu

private Homepage
Mit Zitat antworten
  #12 (permalink)  
Alt 27-04-2009, 15:10
Benutzerbild von onemorenerd onemorenerd
  Moderator
Links : Onlinestatus : onemorenerd ist offline
Registriert seit: Mar 2005
Ort: Berlin
Beiträge: 9.471
onemorenerd wird schon bald berühmt werdenonemorenerd wird schon bald berühmt werden
Standard

Zitat:
Original geschrieben von UzumakiNaruto
und du musst immer überprüfen ob es neue nachrichten gibt .. bei jedem seitenaufruf .. da wirst du NIE drumrumkommen
Diese Prüfung muss aber nicht zwangsläufig ein COUNT() sein, im Idealfall ist dazu überhaupt keine DB-Anfrage notwendig. Der Wert kann schon fertig in $_SESSION stehen.
Mit Zitat antworten
  #13 (permalink)  
Alt 27-04-2009, 15:15
h3ll
 Registrierter Benutzer
Links : Onlinestatus : h3ll ist offline
Registriert seit: Mar 2008
Beiträge: 3.578
h3ll befindet sich auf einem aufstrebenden Ast
Standard

Aber woher weiß die Session, dass inzwischen eine neue Nachricht gekommen ist? Das heißt man würde solange keine neuen Nachrichten empfangen können, bis irgendwann die Session gelöscht oder eine neue Session erstellt wird.
Mit Zitat antworten
  #14 (permalink)  
Alt 27-04-2009, 15:47
martinm79
 Registrierter Benutzer
Links : Onlinestatus : martinm79 ist offline
Registriert seit: Jan 2004
Ort: Deutschland
Beiträge: 744
martinm79 ist zur Zeit noch ein unbeschriebenes Blatt
Standard

Also vielen Dank für den super Hinweis.
Bei mir hat es Klick gemacht.

Also meine Abfrage war zwar richtig, aber die vorgehensweise nicht.
Ich bereite mal gleich was vor. Will auch gleich mal die Zeit messen.
__________________
Gut geraten ist halb gewußt.
Mit Zitat antworten
  #15 (permalink)  
Alt 27-04-2009, 15:55
UzumakiNaruto
 Registrierter Benutzer
Links : Onlinestatus : UzumakiNaruto ist offline
Registriert seit: Nov 2004
Beiträge: 642
UzumakiNaruto befindet sich auf einem aufstrebenden Ast
Standard

Zitat:
Original geschrieben von h3ll
Aber woher weiß die Session, dass inzwischen eine neue Nachricht gekommen ist? Das heißt man würde solange keine neuen Nachrichten empfangen können, bis irgendwann die Session gelöscht oder eine neue Session erstellt wird.

oder die session var geändert wird
__________________
Gruß
Uzu

private Homepage
Mit Zitat antworten
Antwort

Lesezeichen


Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)
 

Themen-Optionen
Thema bewerten
Thema bewerten:

Forumregeln
Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are an


PHP News

ebiz-trader 7.5.0 mit PHP7 Unterstützung veröffentlicht
ebiz-trader 7.5.0 mit PHP7 Unterstützung veröffentlichtDie bekannte Marktplatzsoftware ebiz-trader ist in der Version 7.5.0 veröffentlicht worden.

28.05.2018 | Berni

Wissensbestand in Unternehmen
Wissensbestand in UnternehmenLebenslanges Lernen und Weiterbilden sichert Wissensbestand in Unternehmen

25.05.2018 | Berni


 

Aktuelle PHP Scripte

PHP Server Monitor

PHP Server Monitor ist ein Skript, das prüft, ob Ihre Websites und Server betriebsbereit sind.

11.09.2018 Berni | Kategorie: PHP/ Security
PHP WEB STATISTIK ansehen PHP WEB STATISTIK

Die PHP Web Statistik bietet Ihnen ein einfach zu konfigurierendes Script zur Aufzeichnung und grafischen und textuellen Auswertung der Besuchern Ihrer Webseite. Folgende zeitlichen Module sind verfügbar: Jahr, Monat, Tag, Wochentag, Stunde Folgende son

28.08.2018 phpwebstat | Kategorie: PHP/ Counter
Affilinator - Affilinet XML Produktlisten Skript

Die Affilinator Affilinet XML Edition ist ein vollautomatisches Skript zum einlesen und darstellen der Affili.net (Partnerprogramm Netzwerk) Produktlisten und Produktdaten. Im Grunde gibt der Webmaster seine Affilinet PartnerID ein und hat dann unmittelb

27.08.2018 freefrank@ | Kategorie: PHP/ Partnerprogramme
 Alle PHP Scripte anzeigen

Alle Zeitangaben in WEZ +2. Es ist jetzt 17:47 Uhr.