Schrift
Wiki:Tipp zum Debugging: use Data::Dumper; local $Data::Dumper::Useqq = 1; print Dumper \@var;
[thread]3668[/thread]

erste Abfrage dauert lange...

Leser: 1


<< |< 1 2 3 4 >| >> 32 Einträge, 4 Seiten
olruebe01
 2006-03-27 11:02
#34142 #34142
User since
2006-01-19
192 Artikel
BenutzerIn
[default_avatar]
Halo,

ich experimentiere gerade mit meinen erstenSQL-Erfahrungen.

Ich habe eine kleine DB, in der nur wenige Einträge sind.
ICh möchte Abfragen, ob ein Eintrag vorhanden ist oder nicht.
Bei der ersten Abfrage dauert dies recht lange (2-3 Sekuden). Die folgenden sind blitzschnell.

Mache ich aber für etwa 15 Sekunden gar nichts und fange dann wieder an, dauert es wieder lange.

Ich habe das gleiche Script auch auf einem anderen Server, der meiner Meinung nach die gleiche Konfoguration hat und hier habe ich diese Probleme nicht. Hier geht es IMMER schnell, also auch schon bei der ersten Abfrage.

Wo muss ich anfangen zu suchen?

Das Scripct läuft in Mod-Perl und die Abfrage sieht so aus:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
use CGI::Carp qw(fatalsToBrowser);
#Dateiflock
use Fcntl qw(:DEFAULT :flock);
use CGI qw(:standard);
use CGI;
#use Apache::DBI();
use DBI;
my $datenbank = "blacklist";
my $datenbankhost = "localhost";
my $datenbankuser = "XXXXX";
my $datenbankpw = "YYYYY";

##########################################################
$fehlermeldung = "<li>Fehler bei der Datenbankverbindung aufgetreten. Bitte ueberpruefen Sie die Angaben";
$dbh = DBI->connect("DBI:mysql:$datenbank:$datenbankhost","$datenbankuser","$datenbankpw") || fehlerausgabe($fehlermeldung);
##########################################################
$sth = $dbh->prepare("SELECT art FROM `blacklist` WHERE item = $FORMDATA{item} and Galerie = '$FORMDATA{Galerie}'");
print "SELECT art FROM `blacklist` WHERE item = $FORMDATA{item} and Galerie = '$FORMDATA{Galerie}'";
$sth->execute or die DBI->errstr;
$ergebnis =  $sth->fetchrow_array();
$dbh->disconnect; # DB Connect beenden


Apache::DBI kann ich noch nicht verwenden, da noch nciht installiert. Allerdings habe ich dies zum Vergleich auch bei dem "schnellen Server" mal weggelassen und er ist dennoch VIEL schneller bei der ERSTEN Abfrage. Ab der ersten sind beide gleich schnell...

Mir fehlt einach der Ansatz, so ich suchen muss.

Danke und Gruß,
Oliver
renee
 2006-03-27 11:24
#34143 #34143
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
[quote=olruebe01,27.03.2006, 09:02][...]

Ich habe das gleiche Script auch auf einem anderen Server, der meiner Meinung nach die gleiche Konfoguration hat und hier habe ich diese Probleme nicht. Hier geht es IMMER schnell, also auch schon bei der ersten Abfrage.

[...][/quote]
"meiner Meinung nach" ist sehr ungenau. Hast Du die Konfiguration schon mal verglichen??

*) Gleiches OS?
*) Gleicher DB-Server?
*) Gleiche Modul-Versionen?
*) Gleicher Webserver (auch Version gleich)?
*) Gleiche Perl-Version?


Übrigens solltest Du Dir mal im Wiki den Wiki:Artikel über CGI-Sicherheit durchlesen - vorallem den Abschnitt über die DB-Abfragen...
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
master
 2006-03-27 12:05
#34144 #34144
User since
2003-10-20
610 Artikel
BenutzerIn
[default_avatar]
Vielleicht liegts am Browser, der hat die Seite noch am cache, darum kommt sie schneller.

mach mal shift + reload... ist dann langsam oder schnell?

wenn langsam = prüf mal die verbindung, server oder
vielleicht hast du bei der DB keine indizies oder primärschlüssel gesetzt sowas wirkt sich extrem aus.

nur so als Anhaltspunkte. :-)
$i='re5tsFam ^l\rep';$i=~s/[^a-z| ]//g;$\= reverse "\U!$i";print;
olruebe01
 2006-03-27 13:20
#34145 #34145
User since
2006-01-19
192 Artikel
BenutzerIn
[default_avatar]
Hallo,

mal wieder Danke für die schnellen Antworten.
Am Browsercache liegts nicht, da ich verschiedene "Werte" abgefragt habe und sich somit auch die URL immer geändert hat.

Indizes sind gesetzt.

@ Renee: Gleiches OS, Webserver und DB-Server: ja
Module und Perl: ??? Keine Ahnung, wo ich das rausbekomme. Wenn ich es wüsste, wüsste ich aber auchn icht weiter.

Den Artikel habe ich eben gelesen aber soll ich da eine Warnung erkennen?

Apache::DBI wurde eben installiert. Ich werde jetzt mal experimentieren.

Dieses Modul MUSS auch so aufgerufen werden, oder?
Der schnellere Server hatte dieses Modul schon, allerdings hatte ich aus dem Script "Use Apache::DBI" rausgenommen, um einen Vergleich anstellen zu können.

Also jetzt, mit Apache::DBI, ist es auch auf dem "langsamen Server" schon bei dem ersten Aufruf schnell. Zumindest ist auf den ersten Blick mit dem blossen Auge kein Unterschied zu ekennen...
olruebe01
 2006-03-27 13:25
#34146 #34146
User since
2006-01-19
192 Artikel
BenutzerIn
[default_avatar]
Nachtrag:

ALLE Abfragen (erste und weitere) dauern jetzt etwa 0,02 Sekunden. Einzige Änderung: Apache::DBI
nepos
 2006-03-27 13:28
#34147 #34147
User since
2005-08-17
1420 Artikel
BenutzerIn
[Homepage] [default_avatar]
Zum Thema Sicherheit:
Du nutzt zum einen Daten, die vom User kommen ohne sie zu pruefen. Das ist ein boeses Foul in Sachen Sicherheit. Nie den Daten trauen, die man von ausserhalb bekommt!
Zum anderen baust du diese ungeprueften Parameter auch gleich direkt in dein SQL-Statement ein. Das schreit nach Dingen wie SQL-Injection.
Besser waere:
Code (perl): (dl )
1
2
sth = $dbh->prepare("SELECT art FROM `blacklist` WHERE item = ? and Galerie = ?");
$sth->execute($FORMDATA{item},$FORMDATA{Galerie}) or die DBI->errstr;


Was mir persoenlich noch besser gefaellt, weil kuerzer (und bei dir gehts sogar nur um eine Zeile):
Code (perl): (dl )
@ergebnis = selectrow_array(qq{SELECT art FROM `blacklist` WHERE item = ? and Galerie = ?},undef,$FORMDATA{item},$FORMDATA{Galerie});


Ach ja und ein
Code (perl): (dl )
use strict;
kann auch nie schaden ;)
olruebe01
 2006-03-27 13:41
#34148 #34148
User since
2006-01-19
192 Artikel
BenutzerIn
[default_avatar]
Hi nepos,

wo liegt der Unterschied? Was könnte man anstellen, wenn die Frage nur lautet, ob ein gewisser Wert eingetragen ist oder nicht?
DB ist für mich neu aber was kann man bei einer solchen Anfrage kaputt machen?
master
 2006-03-27 13:52
#34149 #34149
User since
2003-10-20
610 Artikel
BenutzerIn
[default_avatar]
Mach doch sonst ein Int($FORMDATA{item}) vorher.
Code: (dl )
item = $FORMDATA{item}

ok das ist klar unsicher..
Code: (dl )
and Galerie = '$FORMDATA{Galerie}'

Das ist aber sicher, da es mysql-gequotet ist.


@nepos:
deine 2. Version würde mir gefallen, jedoch kann man so das Statement nicht mehr lesen. gibts keinen besseren Weg?

@olruebe01:
am besten solltest du so oder so nicht das Statement direkt übergeben. prüf es voher mit einer eigenen funktion

Code: (dl )
1
2
3
4
&prepare();

sub mein_prepare
{$dbh->prepare($_);}


Dies klingt etwas unnütz, kann dir aber sehr helfen, wenn z. B. später mal "->prepare" nicht mehr unterstützt werden sollte. So kannst du auch später das ganze umbauen, parsen usw. Das würde ich besonders bei SQL abfragen und Dateisystem-sachen machen.
Zudem kanns du so später das Stament z.B. parsen und für z. B. mssql oder oracle usw. anpassen, ohne 90% des codes jeweils ändern zu müssen..

Ich habe mir sowas gebastelt.
Code: (dl )
1
2
sql_open($state,$con);
sql_close($con);
$i='re5tsFam ^l\rep';$i=~s/[^a-z| ]//g;$\= reverse "\U!$i";print;
master
 2006-03-27 13:59
#34150 #34150
User since
2003-10-20
610 Artikel
BenutzerIn
[default_avatar]
[quote=olruebe01,27.03.2006, 11:41]DB ist für mich neu aber was kann man bei einer solchen Anfrage kaputt machen?[/quote]
Code: (dl )
item = $FORMDATA{item}


da du das aus einem Formular holst.
könnte der Angreiffer im Formular folgendes eintippen:
'1; Delete From blacklist --'  (oder so änhlich)
danach wird es in deinem Programm ungefähr so zusammengesetzt:
select bla bla....   where item = 1; DELETE
FROM 'blacklist' --


So kann der angreiffer deine Tabellen löschen, seinsehen und alles machen was er will. Strings musst du im SQL immer in '' setzen... bei Werten, Id's usw. SICHERSTELLEN, das es sich nur um eine Zahl handelt.
ganz simpel z.B. mit int() oder einer regexp.\n\n

<!--EDIT|master|1143453596-->
$i='re5tsFam ^l\rep';$i=~s/[^a-z| ]//g;$\= reverse "\U!$i";print;
renee
 2006-03-27 14:25
#34151 #34151
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Perlversion bekommst Du mit perl -v auf der Kommandozeile raus. Wenn Du nur mit CGI-Skripten arbeiten kannst, dann mach:
Code: (dl )
1
2
3
4
5
6
7
8
9
#!/usr/bin/perl

use strict;
use warnings;
use DBI;

my $var = `perl -v`;

print "Content-type: text/html\n\n", $var,"<br /><br />",$DBI::VERSION;


//Mod: Stimmt nicht ganz, so ohne Header. So stimmt es eher.
Code erweitert ;)

@GwenDragon: Danke...\n\n

<!--EDIT|renee|1143457801-->
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
<< |< 1 2 3 4 >| >> 32 Einträge, 4 Seiten



View all threads created 2006-03-27 11:02.