Later sql laden
Ik heb een MySQL query die 13 sec duurt nu is mijn vraag kan ik 1e gewoon mijn html pagina en dat die query op de achtergrond wordt uitgevoerd en als hij dan klaar laat ie zien wat ie terug heeft gehad.
Hoe komt het dat de query zo traag is? Wat doe je ooit?
Ik heb 4,5 miljoen rije en elek rij vergelijk ik met 50.000 rije uit een andere tabel dus vandaar
Het zou zomaar kunnen door de query slimmer te maken een behoorlijke snelheidswinst te behalen is.
Denk daarbij aan indexen plaatsen e.d.
Heb je al eens een EXPLAIN uitgevoerd op de query?
Als je echter toch een HTML-pagina wilt tonen met de uitkomst, kan dat bijvoorbeeld met een doodgewoon <iframe> wanneer je niet afhankelijk wilt zijn van Ajax en JavaScript.
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
SELECT
count(uid) as uid
FROM
`table`
WHERE
hostname NOT IN (SELECT
url
FROM
Hosters)
GROUP BY hostname
HAVING uid > 20
?>
SELECT
count(uid) as uid
FROM
`table`
WHERE
hostname NOT IN (SELECT
url
FROM
Hosters)
GROUP BY hostname
HAVING uid > 20
?>
Gewijzigd op 19/11/2013 13:06:07 door Peter de Beer
Peter de Beer op 19/11/2013 11:39:32:
Ik heb 4,5 miljoen rije en elek rij vergelijk ik met 50.000 rije uit een andere tabel dus vandaar
Indien gewenst ...
Je zou met Ajax de query kunnen triggeren (is al verteld).
Eventueel kan je dit doen met meerdere verzoeken. Je houdt in javascript een teller bij, en elk verzoek doe je dan een half miljoen rijen.
In dat geval heb je dus ook een progress bar, zowat gratis.
Interesse?
Kris Peeters op 19/11/2013 13:12:43:
In dat geval heb je dus ook een progress bar, zowat gratis.
Interesse?
Peter de Beer op 19/11/2013 11:39:32:
Ik heb 4,5 miljoen rije en elek rij vergelijk ik met 50.000 rije uit een andere tabel dus vandaar
In dat geval heb je dus ook een progress bar, zowat gratis.
Interesse?
Wat? heb je iets te koop ?
En volgens mij kun je jouw query sneller maken met gebruik van JOINs (maar ik ben geen expert hierin...)
Gewijzigd op 19/11/2013 13:42:14 door Wouter J
Peter de Beer op 19/11/2013 13:26:41:
Wat? heb je iets te koop ?
Ik bedoel: is het de moeite waard dat ik notepad2.exe boven haal en begin te typen aan een voorbeeld scriptje.
Hier dus een voorbeeldje
Copy/paste dit in een leeg .php bestand
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
<?php
if (!empty($_GET['ajax'])) {
// ajax verzoek
// $_GET['index'] is eerst 0, dan 1, dan 2 ...
if ($_GET['index'] > 10) {
echo -1;
exit;
}
sleep(1); // bij jou duurt 1 tiende van jouw query ongeveer een seconde
echo '$_GET["index"]: ' . $_GET['index'];
exit; // nooit vergeten na een Ajax verzoek. Anders wordt de rest van de code nog uitgevoerd
}
?>
<!DOCTYPE html>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script>
var index = 0;
$(document).ready(function() {
var button = $('#button');
var messages = $('#messages');
// events
button.on('click', function(e) {
trigger_sql();
});
function trigger_sql() {
$.ajax({
url: '?ajax=1',
data: {index: index},
success: function (data) {
if (data == -1) { // indien de server -1 terug geeft, zien we dit als een resultaat om te stoppen
return;
}
else {
messages.html(
'bericht van de server: ' + data
+ '<br> progress: ' + (100 * index / 10) + '%'
);
}
index++;
trigger_sql();
}
});
}
});
</script>
</head>
<body>
<input type="button" id="button" value="KLIK">
<div id="messages"></div>
</body>
</html>
if (!empty($_GET['ajax'])) {
// ajax verzoek
// $_GET['index'] is eerst 0, dan 1, dan 2 ...
if ($_GET['index'] > 10) {
echo -1;
exit;
}
sleep(1); // bij jou duurt 1 tiende van jouw query ongeveer een seconde
echo '$_GET["index"]: ' . $_GET['index'];
exit; // nooit vergeten na een Ajax verzoek. Anders wordt de rest van de code nog uitgevoerd
}
?>
<!DOCTYPE html>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script>
var index = 0;
$(document).ready(function() {
var button = $('#button');
var messages = $('#messages');
// events
button.on('click', function(e) {
trigger_sql();
});
function trigger_sql() {
$.ajax({
url: '?ajax=1',
data: {index: index},
success: function (data) {
if (data == -1) { // indien de server -1 terug geeft, zien we dit als een resultaat om te stoppen
return;
}
else {
messages.html(
'bericht van de server: ' + data
+ '<br> progress: ' + (100 * index / 10) + '%'
);
}
index++;
trigger_sql();
}
});
}
});
</script>
</head>
<body>
<input type="button" id="button" value="KLIK">
<div id="messages"></div>
</body>
</html>
super bedankt !!!
Peter de Beer op 19/11/2013 13:05:38:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
SELECT
count(uid) as uid
FROM
`table`
WHERE
hostname NOT IN (SELECT
url
FROM
Hosters)
GROUP BY hostname
HAVING uid > 20
?>
SELECT
count(uid) as uid
FROM
`table`
WHERE
hostname NOT IN (SELECT
url
FROM
Hosters)
GROUP BY hostname
HAVING uid > 20
?>
AUW een NOT IN met een subquery op een dergelijk aantal records, dat is inderdaad vragen om moeilijkheden. Probeer het eens anders zou ik zeggen:
Code (php)
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
SELECT COUNT(uid) as uid
FROM (
SELECT hostname, uid
FROM `table` a
LEFT JOIN hosters b ON a.hostname = b.url
WHERE b.url IS NULL
) c
GROUP BY hostname
HAVING uid > 20;
FROM (
SELECT hostname, uid
FROM `table` a
LEFT JOIN hosters b ON a.hostname = b.url
WHERE b.url IS NULL
) c
GROUP BY hostname
HAVING uid > 20;
Nu kan het zijn dat de query niet helemaal werkt, aangezien ik bijvoorbeeld niet kan zien waar uid vandaan komt (uit welke tabel). Maar als het wel werkt gok ik dat het aanzienlijk sneller zal zijn....
Gewijzigd op 19/11/2013 14:46:14 door Erwin H
En dan de GROUP BY op hostname terwijl die niet in de select list staat, in MySQL kan dat, maar in ANSI SQL niet. Lijkt me trouwens ook wel handig om erbij te hebben.
Erwin H op 19/11/2013 14:45:28:
AUW een NOT IN met een subquery op een dergelijk aantal records, dat is inderdaad vragen om moeilijkheden. Probeer het eens anders zou ik zeggen:
Nu kan het zijn dat de query niet helemaal werkt, aangezien ik bijvoorbeeld niet kan zien waar uid vandaan komt (uit welke tabel). Maar als het wel werkt gok ik dat het aanzienlijk sneller zal zijn....
Peter de Beer op 19/11/2013 13:05:38:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
SELECT
count(uid) as uid
FROM
`table`
WHERE
hostname NOT IN (SELECT
url
FROM
Hosters)
GROUP BY hostname
HAVING uid > 20
?>
SELECT
count(uid) as uid
FROM
`table`
WHERE
hostname NOT IN (SELECT
url
FROM
Hosters)
GROUP BY hostname
HAVING uid > 20
?>
AUW een NOT IN met een subquery op een dergelijk aantal records, dat is inderdaad vragen om moeilijkheden. Probeer het eens anders zou ik zeggen:
Code (php)
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
SELECT COUNT(uid) as uid
FROM (
SELECT hostname, uid
FROM `table` a
LEFT JOIN hosters b ON a.hostname = b.url
WHERE b.url IS NULL
) c
GROUP BY hostname
HAVING uid > 20;
FROM (
SELECT hostname, uid
FROM `table` a
LEFT JOIN hosters b ON a.hostname = b.url
WHERE b.url IS NULL
) c
GROUP BY hostname
HAVING uid > 20;
Nu kan het zijn dat de query niet helemaal werkt, aangezien ik bijvoorbeeld niet kan zien waar uid vandaan komt (uit welke tabel). Maar als het wel werkt gok ik dat het aanzienlijk sneller zal zijn....
Code (php)
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
SELECT
COUNT(uid) as uid, hostname
FROM
(SELECT
hostname, uid
FROM
`table_a`
LEFT JOIN table_b ON `table_a`.`hostname` = table_b.url
WHERE
table_b.url IS NULL)
GROUP BY hostname
COUNT(uid) as uid, hostname
FROM
(SELECT
hostname, uid
FROM
`table_a`
LEFT JOIN table_b ON `table_a`.`hostname` = table_b.url
WHERE
table_b.url IS NULL)
GROUP BY hostname
Ik heb aan gepast op mijn situatie maar ik krijg steeds een error
Peter de Beer op 20/11/2013 09:03:32:
Ik heb aan gepast op mijn situatie maar ik krijg steeds een error
En welke error dat is mogen wij niet weten?
Maar nogmaals die is helemaal niet nodig:
Code (php)
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
SELECT
COUNT(uid) as uid, hostname
FROM
table_a
LEFT JOIN table_b ON table_a.hostname = table_b.url
WHERE
table_b.url IS NULL
GROUP BY hostname
COUNT(uid) as uid, hostname
FROM
table_a
LEFT JOIN table_b ON table_a.hostname = table_b.url
WHERE
table_b.url IS NULL
GROUP BY hostname
Let wel op dat je indexen zet op de kolommen waarop je joined
- SanThe - op 20/11/2013 09:06:55:
En welke error dat is mogen wij niet weten?
Peter de Beer op 20/11/2013 09:03:32:
Ik heb aan gepast op mijn situatie maar ik krijg steeds een error
En welke error dat is mogen wij niet weten?
Natuurlijk
Error Code: 1248. Every derived table must have its own alias 0,001 sec
Toevoeging op 20/11/2013 09:37:32:
Ger van Steenderen op 20/11/2013 09:19:25:
Er bestaat geen alias voor de subquery achter de FROM en dat moet wel.
Maar nogmaals die is helemaal niet nodig:
Let wel op dat je indexen zet op de kolommen waarop je joined
Maar nogmaals die is helemaal niet nodig:
Code (php)
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
SELECT
COUNT(uid) as uid, hostname
FROM
table_a
LEFT JOIN table_b ON table_a.hostname = table_b.url
WHERE
table_b.url IS NULL
GROUP BY hostname
COUNT(uid) as uid, hostname
FROM
table_a
LEFT JOIN table_b ON table_a.hostname = table_b.url
WHERE
table_b.url IS NULL
GROUP BY hostname
Let wel op dat je indexen zet op de kolommen waarop je joined
Idexen heb ik er op zitten
Error Code: 1052. Column 'uid' in field list is ambiguous 0,001 sec
COUNT(uid)
Ambiguous krijg je omdat je in beide tabellen kolommen met dezelfde naam hebt, en in de select niet aangeeft uit welke tabel je hem moet hebben. Gebruik standaard FQN's (Fully Qualified Names - table_a.uid -) in queries met joines, zit je altijd goed.
Code (php)
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
SELECT
COUNT(table_a.uid) as uid
FROM
table_a
LEFT JOIN
table_b ON table_a.`hostname` = table_b.url
WHERE
table_b.url IS NULL
GROUP BY hostname
HAVING uid > 20;
COUNT(table_a.uid) as uid
FROM
table_a
LEFT JOIN
table_b ON table_a.`hostname` = table_b.url
WHERE
table_b.url IS NULL
GROUP BY hostname
HAVING uid > 20;
197 row(s) returned 10,870 sec / 0,000 sec
Het blijft hoe dan ook een draak van een querie.