richtige MYSQL- Abfrage

live4music

Mitglied
Hallo, ich hab wieder mal ne kleine Frage an euch, ich kämpfe immer noch mit meiner MYSQL Auslastung. Hab jetzt viele unnötige Abfragen gelöscht oder umgeschrieben. Und ich wollte euch mal fragen, ist diese Funtion richtig ? die ich hier geschrieben haben. Oder macht es einen Sinn solche Abfragen zu schreiben ?

PHP:
function ItsMe($sql)
{

	global $DB;
	global $sess;


		$GetMe = $DB->query("SELECT * FROM users WHERE id = '$sess'");
		$rowMe = $DB->fetch_array($GetMe);
	
		return $rowMe[$sql];
	    
}

also ich habe viele andere Mysql Abfragen nur durch diese Funktion ersetzt und wenn ich was aus Users brauche rufe ich immer diese Funktion auf. Ich bin kein Profi und bin noch dabei PHP zu lernen. Und kämpfe gerade mit der Auslastung wenn mehr als 20 Leute online sind dann liegt die bei 40 oder mehr % :(. Und ich weiß jetzt nicht wo genau der Fehler liegt :(.
 
und noch was sollte man die Results besser in Variablen speichern so

$username = $row->username;
$password = $row->password;

oder einfach so $row->username abfragen ? wie ist es am besten für MYSQL ?
 
und wenn ich was aus Users brauche rufe ich immer diese Funktion auf.

Wie oft kommt das denn bei einem Seitenaufruf vor? Was du da machst ist schrecklich. Du holst dir alle Spalten und nimmst doch nur eine. Das ist unnötiger Datenverkehr. Und noch schlimmer ist es, wenn du das mehrfach pro Seitenaufruf machst, z.B. für jede Spalte extra (hoffentlich nicht.). Ein Schritt wäre z.B. mal den Stern durch die Spalte zu ersetzen. Du willst doch ohnehin nur genau diese eine.
 
Tipp: Benutz EXPLAIN

Ist auf der id-Spalte denn überhaupt ein Index? Z.B. Unique? Wenn nicht mach mal folgendes:

Öffne phpMyAdmin und logge dich ein. Wechsel in die DB, die die Tabellen für deine Abfrage enthält. Gehe ins SQL-Tab. Führe dieses Statement aus:

SQL:
SELECT id FROM users LIMIT 1;
-- Merke die ID durch kopieren in die Zwischenablage, dann diesen Query:

EXPLAIN SELECT * FROM users WHERE id = 'hier_die_gemerkte_id';
-- Kopiere die Ausgabe in Wordpad oder ein anderes Text-Verabeitungsprogramm zum Vergleichen

Dann fügst du der Spalte id den Unique-Index hinzu und führst noch mal den EXPLAIN-Query aus. Dann vergleichst du die Ergebnisse.
 
Wie oft kommt das denn bei einem Seitenaufruf vor? Was du da machst ist schrecklich. Du holst dir alle Spalten und nimmst doch nur eine. Das ist unnötiger Datenverkehr. Und noch schlimmer ist es, wenn du das mehrfach pro Seitenaufruf machst, z.B. für jede Spalte extra (hoffentlich nicht.). Ein Schritt wäre z.B. mal den Stern durch die Spalte zu ersetzen. Du willst doch ohnehin nur genau diese eine.


hm ich dachte so währe es besser :((

sooo, hab jetzt den Stern durch $sql ersetzt und hole nur eine bestimmte Spalte. Also ich soll besser für jede Datei wo ich welche Daten aus der User Tabelle brachen eine Abfrage schreiben staat dieser ? diese Funktion steht bei mir in Fuintion.php und von dort frage ich immer was ich brache aber so wie ich es verstanden habe ist es total falsch.
 
Tipp: Benutz EXPLAIN

Ist auf der id-Spalte denn überhaupt ein Index? Z.B. Unique? Wenn nicht mach mal folgendes:

Öffne phpMyAdmin und logge dich ein. Wechsel in die DB, die die Tabellen für deine Abfrage enthält. Gehe ins SQL-Tab. Führe dieses Statement aus:

SQL:
SELECT id FROM users LIMIT 1;
-- Merke die ID durch kopieren in die Zwischenablage, dann diesen Query:

EXPLAIN SELECT * FROM users WHERE id = 'hier_die_gemerkte_id';
-- Kopiere die Ausgabe in Wordpad oder ein anderes Text-Verabeitungsprogramm zum Vergleichen

Dann fügst du der Spalte id den Unique-Index hinzu und führst noch mal den EXPLAIN-Query aus. Dann vergleichst du die Ergebnisse.


die ID hat bei mir PRIMARY

SIMPLE users const PRIMARY PRIMARY 2 const 1
 
Zuletzt bearbeitet:
Du könntest bspw. auch das Ergebnis des Datensatzes irgendwo global hinterlegen. Hast du deine Datenbank-Zugriffe evtl. irgendwie abstrahiert? Man könnte so tricksen:

PHP:
function ItsMe($sql)
{

    global $DB;
    global $sess;

    static $me;

    if( !$me )
    {
        $GetMe = $DB->query("SELECT * FROM users WHERE id = '$sess'");
        $me = $DB->fetch_array($GetMe);
    }
    return $me[$sql];
}

Damit sollte nur beim ersten mal, wenn keine Daten vorhanden sind, die DB abgefragt werden, alle weiteren Abfragen gehen direkt auf $me, weil da schon was drin steht. Keine Garantie, dass das so funktioniert.

Du könntest natürlich auch eine vernünftige Abstraktionsschicht einbauen und mit Singleton-Pattern arbeiten:

PHP:
class MeObject
{
  private $me = null;
  private static $instance = null;

  /**
   * Private constructor to respect singleton pattern
   * @return MeObject
   ********************/
  private function __construct()
  {
      global $DB;
      global $sess;
      $GetMe = $DB->query("SELECT * FROM users WHERE id = '$sess'");
      $this->me = $DB->fetch_array($GetMe);
  }

  /**
   * Creates a new single instance of MeObject
   * @return MeObject
   ********************/
  public static function getInstance()
  {
      if(self::$instance == null)
      {
          self::$instance = new MeObject();
      }
      assert(is_a(self::$instance, 'MeObject'));  // Hier hatte sich wohl der Java-Teufel eingeschlichen ;-)
      return self::$instance;
  }

  /**
   * Retrieve the user information as array
   * @return $array
   ********************/
  public function getMe()
  {
      return $this->me;
  }
}

echo "<pre>";
var_dump(
  MeObject::getInstance()->getMe()
);
echo "</pre>";

Sieht doch prima aus und ist performant ;-)
 
Zuletzt bearbeitet:
Wobei sich natürlich die Frage stellt: Ist das der einzige Query der ausgeführt wird? Was käme noch in Frage? Hast du evtl. irgendwelche JOINs eingebaut?

Du kannst natürlich Fleißarbeit leisten und alle Queries mal durch Explain laufen lassen. Dann lernst du auch gleich, wie eine DB intern arbeitet und wie man das zu seinem Vorteil nutzen kann: Stichwort Optimierung.
 
Wobei sich natürlich die Frage stellt: Ist das der einzige Query der ausgeführt wird? Was käme noch in Frage? Hast du evtl. irgendwelche JOINs eingebaut?

Du kannst natürlich Fleißarbeit leisten und alle Queries mal durch Explain laufen lassen. Dann lernst du auch gleich, wie eine DB intern arbeitet und wie man das zu seinem Vorteil nutzen kann: Stichwort Optimierung.


Ja JOINS hab ich auch, aber wenn ich JOIN nutze, dann mach ich eine neue Abfrage und nicht die über ItsMe();

ja ich werde jetzt das alles mal durchgucken und neue machen und noch einmal danke!, hab jetzt wider was neues dazu gelernt. Ich guck ja alles im Web wenn ich irgendwas nicht weiß und so wie ich es jetzt gemerkt habe schreiben da viele nur schrott rein. Werde jetzt besser aufpasse was ich da abgucke und mache.
 
Zurück