AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Netzwerke Wie MySQL-Abfrage optimieren? (große Tabelle, Dauer: 0.2s)
Thema durchsuchen
Ansicht
Themen-Optionen

Wie MySQL-Abfrage optimieren? (große Tabelle, Dauer: 0.2s)

Ein Thema von Matze · begonnen am 3. Mär 2009 · letzter Beitrag vom 3. Mär 2009
Antwort Antwort
Seite 1 von 3  1 23      
Benutzerbild von Matze
Matze
(Co-Admin)

Registriert seit: 7. Jul 2003
Ort: Schwabenländle
14.929 Beiträge
 
Turbo Delphi für Win32
 
#1

Wie MySQL-Abfrage optimieren? (große Tabelle, Dauer: 0.2s)

  Alt 3. Mär 2009, 09:20
Hallo,

ich habe 2 MySQL-Tabellen, die wie folgt aufgebaut sind:

SQL-Code:
CREATE TABLE `log_parser_ips` (
  `ip_from` INTEGER(10) UNSIGNED NOT NULL DEFAULT '0',
  `ip_to` INTEGER(10) UNSIGNED NOT NULL DEFAULT '0',
  `cc` CHAR(2) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
  PRIMARY KEY (`ip_from`),
  UNIQUE KEY `ip_to` (`ip_to`),
  UNIQUE KEY `ip_from` (`ip_from`),
  KEY `cc` (`cc`)
)ENGINE=MyISAM
ROW_FORMAT=FIXED CHARACTER SET 'utf8' COLLATE 'utf8_unicode_ci';
SQL-Code:
CREATE TABLE `log_parser_countries` (
  `cc` CHAR(2) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
  `country` VARCHAR(64) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
  PRIMARY KEY (`cc`)
)ENGINE=MyISAM
CHARACTER SET 'utf8' COLLATE 'utf8_unicode_ci';
Die Tabelle "log_parser_ips" enthält die IP-Adressenbereiche (ip_from / ip_to) und ordnet diese einem Ländercode (cc) zu.
Die Tabelle ""log_parser_countries" ordnet den Ländercodes (cc) den Ländernamen (country) zu.

Anhand der IP ermittel ich das Land folgendermaßen:

SQL-Code:
SELECT c.country, c.cc FROM log_parser_countries c
   JOIN log_parser_ips i
      ON i.cc = c.cc
   WHERE i.ip_from <= 123456789 AND i.ip_to >= 123456789
   LIMIT 1
Wenn ich die Abfrage ohne "JOIN" ausführe:

SQL-Code:
SELECT c.country, c.cc FROM log_parser_countries c, log_parser_ips i
   WHERE i.ip_from <= 123456789
      AND i.ip_to >= 123456789
      AND i.cc = c.cc
   LIMIT 1
ändert sich nichts, was die Ausführungszeit betrifft. Diese liegt durchschnittlich bei stolzen 0.2 Sekunden.

Wie kann ich das optimieren?

Ich habe schon überlegt, anstelle der Spalte "cc" (CHAR) für die Zuordnung eine Integer-Spalte zu verwenden. Aber ob das so viel bringt, weiß ich nicht.

Grüße, Matze
  Mit Zitat antworten Zitat
Benutzerbild von Bernhard Geyer
Bernhard Geyer

Registriert seit: 13. Aug 2002
17.171 Beiträge
 
Delphi 10.4 Sydney
 
#2

Re: Wie MySQL-Abfrage optimieren? (große Tabelle, Dauer: 0.2

  Alt 3. Mär 2009, 09:22
Zitat von Matze:
Wie kann ich das optimieren?
1, Verwendung von Prepared Statements (und damit zwangsweis Parametrisierte Abfragen)
2, Verwendung von Stored Procedures
Windows Vista - Eine neue Erfahrung in Fehlern.
  Mit Zitat antworten Zitat
Benutzerbild von Matze
Matze
(Co-Admin)

Registriert seit: 7. Jul 2003
Ort: Schwabenländle
14.929 Beiträge
 
Turbo Delphi für Win32
 
#3

Re: Wie MySQL-Abfrage optimieren? (große Tabelle, Dauer: 0.2

  Alt 3. Mär 2009, 10:23
Hallo Bernhard,

danke für deine Antwort.
Ich habe mich mal in die Prepared Statements eingearbeitet, doch ändert sich die Ausführungszeit leider nicht.

Mein PHP-Code schaut so aus:

Code:
$this->[color=#018801]db_connection[/color] = [b][color=#0000ff]new[/color][/b] [color=#018801]mysqli[/color]($conf_db[[color=#df0000]'host'[/color]], $conf_db[[color=#df0000]'user'[/color]], $conf_db[[color=#df0000]'passwd'[/color]], $conf_db[[color=#df0000]'name'[/color]]);
[b][color=#0000ff]if[/color][/b] ([color=#018801]mysqli_connect_errno[/color]())
   [b][color=#0000ff]die[/color][/b]([color=#018801]mysqli_connect_error[/color]() . [color=#df0000]' - '[/color] . [color=#018801]mysqli_connect_errno[/color]());

$this->[color=#018801]db_statement[/color] = $this->[color=#018801]db_connection[/color]->[color=#018801]prepare[/color]([color=#df0000]"SELECT c.country, c.cc FROM log_parser_countries c
   JOIN log_parser_ips i
      ON i.cc = c.cc
   WHERE i.ip_from <= ? AND i.ip_to >= ?
   LIMIT 1"[/color]);
[b][color=#0000ff]if[/color][/b] (!$this->[color=#018801]db_statement[/color])
   [b][color=#0000ff]echo[/color][/b] $this->[color=#018801]db_connection[/color]->[color=#018801]error[/color];

$this->[color=#018801]db_statement[/color]->[color=#018801]bind_param[/color]([color=#df0000]"ii"[/color], $ip, $ip);
[b][color=#0000ff]if[/color][/b] (!$this->[color=#018801]db_statement[/color]->[color=#018801]execute[/color]())
   [b][color=#0000ff]echo[/color][/b] $this->[color=#018801]db_statement[/color]->[color=#018801]error[/color];
   
$this->[color=#018801]db_statement[/color]->[color=#018801]bind_result[/color]($country, $cc);

[b][color=#0000ff]if[/color][/b] (!$this->[color=#018801]db_statement[/color]->[color=#018801]fetch[/color]())
   [b][color=#0000ff]echo[/color][/b] [color=#df0000]'empty mysql result'[/color];

$this->[color=#018801]db_connection[/color]->[color=#018801]close[/color]();
Grüße, Matze


PS: Falls sich das nun zu einer PHP-Frage entwickelt, verschiebe ich das Thema.
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.542 Beiträge
 
Delphi 11 Alexandria
 
#4

Re: Wie MySQL-Abfrage optimieren? (große Tabelle, Dauer: 0.2

  Alt 3. Mär 2009, 10:31
Zitat:
SQL-Code:
UNIQUE KEY `ip_to` (`ip_to`),
  UNIQUE KEY `ip_from` (`ip_from`),
Bist Du sicher, dass das so stimmt? Ich vermute, Du wolltest eine eindeutige Kombination der beiden IPs, oder?
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Daniel
(Co-Admin)

Registriert seit: 30. Mai 2002
Ort: Hamburg
13.919 Beiträge
 
Delphi 10.4 Sydney
 
#5

Re: Wie MySQL-Abfrage optimieren? (große Tabelle, Dauer: 0.2

  Alt 3. Mär 2009, 10:36
Hast Du mal ein Explain-Select darauf losgelassen? Damit könntest Du weitere Indizien auf den Flaschenhals bekommen.
(Einfach das Keyword "EXPLAIN" vor das Statement schreiben und dann in phpMyAdmin oder wo auch immer ausführen.)
Daniel R. Wolf
mit Grüßen aus Hamburg
  Mit Zitat antworten Zitat
mquadrat

Registriert seit: 13. Feb 2004
1.113 Beiträge
 
Delphi XE2 Professional
 
#6

Re: Wie MySQL-Abfrage optimieren? (große Tabelle, Dauer: 0.2

  Alt 3. Mär 2009, 11:04
Ich schließe mich DeddyH an. Ein kombinierter Index würde wohl besser funktionieren
  Mit Zitat antworten Zitat
Benutzerbild von Matze
Matze
(Co-Admin)

Registriert seit: 7. Jul 2003
Ort: Schwabenländle
14.929 Beiträge
 
Turbo Delphi für Win32
 
#7

Re: Wie MySQL-Abfrage optimieren? (große Tabelle, Dauer: 0.2

  Alt 3. Mär 2009, 11:08
Hi,

@Deddy: Hm ich bin mir nicht so ganz sicher, aber da die Zahlen nicht doppelt vorkommen, habe ich UNIQUE gesetzt.
@Daniel: EXPLAIN kannte ich bisher gar nicht. Interessantes Feature, doch mit dem Ergebnis fange ich leider nichts an, was mich bzgl. Performance weiterbringen könnte:

Code:
id   select_txpe  table  type    possible_keys             key      ken_len  ref      rows  Extra
----------------------------------------------------------------------------------------------------------------
1     SIMPLE       i      range   PRIMARY,ip_to,ip_from,cc  PRIMARY  4         NULL     27     Using where
1     SIMPLE       c      eq_ref  PRIMARY                   PRIMARY  6         db.i.cc  1
@mquadrat: Meinst du sowas "PRIMARY KEY (`ip_to`, `ip_from`)"?
Falls ja, auch da merke ich keinen Unterschied.

Grüße, Matze
  Mit Zitat antworten Zitat
mquadrat

Registriert seit: 13. Feb 2004
1.113 Beiträge
 
Delphi XE2 Professional
 
#8

Re: Wie MySQL-Abfrage optimieren? (große Tabelle, Dauer: 0.2

  Alt 3. Mär 2009, 11:12
Das Explain verrät dir in diesem Beispiel, dass er für die Bereichsprüfung die Indizes PRIMARY, ip_to, ip_from und cc einsetzen könnte, sich aber für den PRIMARY entscheidet. Dabei findet er 27 Einträge, die dann mit einem where auf einen reduziert werden.
  Mit Zitat antworten Zitat
Benutzerbild von Matze
Matze
(Co-Admin)

Registriert seit: 7. Jul 2003
Ort: Schwabenländle
14.929 Beiträge
 
Turbo Delphi für Win32
 
#9

Re: Wie MySQL-Abfrage optimieren? (große Tabelle, Dauer: 0.2

  Alt 3. Mär 2009, 11:15
Hi mquadrat,

ok, aber was sagt mir das nun genau? Dass die anderen Indizes überflüssig sind?
Oder kann ich irgendwas herauslesen, damit ich die Abfrage beschleunigen kann?

Grüße, Matze
  Mit Zitat antworten Zitat
mquadrat

Registriert seit: 13. Feb 2004
1.113 Beiträge
 
Delphi XE2 Professional
 
#10

Re: Wie MySQL-Abfrage optimieren? (große Tabelle, Dauer: 0.2

  Alt 3. Mär 2009, 11:18
Wenn das die einzige Query auf die Tabelle ist, dann kannst du die anderen Indizes tatsächlich entfernen. Hat aber eher Einfluß auf die Schreib-Performance. Mittels Explain kann man seine Indizes "tunen". Je weniger Datensätze durch den Index durchkommen, desto besser. Bei nem kombinierten müsste da eigentlich statt der 27 eine 1 stehen..

Hast du davon irgendwo einen Dump, damit man das mal ausprobieren kann?
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 3  1 23      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine 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 aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:21 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz