<?php //LECIMY PRZEZ ULUBIONE KATEGORIE UZYTKOWNIKA SELECT w.id_bazy id_bazy, w.priorytet priorytet, w.widoczne widoczne, w.nazwa nazwa, b.odleglosc odleglosc FROM mobilne_wybrane w WHERE w.id_uzytkownika='$UZYTKOWNIK' \"); { //LECIMY PRZEZ PUNKTY SELECT * FROM mobilne_punkty p WHERE id_bazy='$ulubiona[id_bazy]' \"); { //CZY JUŻ JEST TAKI PUNKT W PLIKU W POBLIŻU? SELECT id FROM mobilne_tmp_punkty WHERE id_uzytkownika='$UZYTKOWNIK' AND nazwa_kategorii='$ulubiona[nazwa]' AND sqrt( pow( (x1+(x2*256)+(x3*256*256)) - ('$punkt[x1]'+('$punkt[x2]'*256)+('$punkt[x3]'*256*256)) , 2 ) + pow( (y1+(y2*256)+(y3*256*256)) - ('$punkt[y1]'+('$punkt[y2]'*256)+('$punkt[y3]'*256*256)) , 2 ) ) < '$ulubiona[odleglosc]' \"); //JEŚLI NIE, TO TRZEBA DODAĆ { INSERT INTO mobilne_tmp_punkty (id_uzytkownika, x1, x2, x3, y1, y2, y3, priorytet, nazwa, opis, widok, numer_kategorii, nazwa_kategorii, operacja) VALUES ('$UZYTKOWNIK', '$punkt[x1]', '$punkt[x2]', '$punkt[x3]', '$punkt[y1]', '$punkt[y2]', '$punkt[y3]', '$ulubiona[priorytet]'-1, '$punkt[nazwa]', '$punkt[opis]', '$ulubiona[widoczne]'-1, '$numer_kategorii', '$ulubiona[nazwa]', 2) \"); } } } ?>
Działa na tabelach:
CREATE TABLE `mobilne_bazy` ( `id` mediumint(1) NOT NULL AUTO_INCREMENT, `kategoria` char(32) NOT NULL DEFAULT '', `nazwa` char(100) DEFAULT '0', `id_ikony` mediumint(1) UNSIGNED NOT NULL DEFAULT '0', `id_uzytkownika` mediumint(1) UNSIGNED NOT NULL DEFAULT '0', `data_utworzenia` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', `prywatna` char(1) NOT NULL DEFAULT 'N', `odleglosc` smallint(1) UNSIGNED NOT NULL DEFAULT '100', `data_aktualizacji` datetime DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=latin2 AUTO_INCREMENT=100 ; CREATE TABLE `mobilne_punkty` ( `id` mediumint(1) UNSIGNED NOT NULL AUTO_INCREMENT, `id_bazy` mediumint(1) UNSIGNED NOT NULL DEFAULT '0', `id_uzytkownika` mediumint(1) UNSIGNED NOT NULL DEFAULT '0', `data` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', `x1` tinyint(1) UNSIGNED NOT NULL DEFAULT '0', `x2` tinyint(1) UNSIGNED NOT NULL DEFAULT '0', `x3` tinyint(1) UNSIGNED NOT NULL DEFAULT '0', `y1` tinyint(1) UNSIGNED NOT NULL DEFAULT '0', `y2` tinyint(1) UNSIGNED NOT NULL DEFAULT '0', `y3` tinyint(1) UNSIGNED NOT NULL DEFAULT '0', `nazwa` char(64) DEFAULT NULL, `opis` char(255) DEFAULT NULL, `niewazny` tinyint(1) UNSIGNED NOT NULL DEFAULT '0', KEY `id` (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=latin2 AUTO_INCREMENT=4950 ; CREATE TABLE `mobilne_tmp_punkty` ( `id` mediumint(1) UNSIGNED NOT NULL AUTO_INCREMENT, `id_uzytkownika` mediumint(1) UNSIGNED NOT NULL DEFAULT '0', `x1` tinyint(1) UNSIGNED NOT NULL DEFAULT '0', `x2` tinyint(1) UNSIGNED NOT NULL DEFAULT '0', `x3` tinyint(1) UNSIGNED NOT NULL DEFAULT '0', `y1` tinyint(1) UNSIGNED NOT NULL DEFAULT '0', `y2` tinyint(1) UNSIGNED NOT NULL DEFAULT '0', `y3` tinyint(1) UNSIGNED NOT NULL DEFAULT '0', `priorytet` tinyint(4) UNSIGNED DEFAULT '0', `nazwa` varchar(64) DEFAULT NULL, `opis` varchar(255) DEFAULT NULL, `widok` tinyint(1) UNSIGNED NOT NULL DEFAULT '0', `numer_kategorii` tinyint(1) UNSIGNED DEFAULT NULL, `nazwa_kategorii` varchar(32) DEFAULT NULL, `operacja` tinyint(1) UNSIGNED NOT NULL DEFAULT '0', PRIMARY KEY (`id`) ) ENGINE=HEAP DEFAULT CHARSET=latin2 AUTO_INCREMENT=104844 ; CREATE TABLE `mobilne_uzytkownicy` ( `id` mediumint(1) UNSIGNED NOT NULL AUTO_INCREMENT, `login` char(64) NOT NULL DEFAULT '', `haslo` char(42) NOT NULL DEFAULT '', `mail` char(255) NOT NULL DEFAULT '', `string` char(50) DEFAULT NULL, `ilosc_na_stronie` smallint(1) UNSIGNED DEFAULT '15', UNIQUE KEY `id` (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=latin2 AUTO_INCREMENT=625 ; CREATE TABLE `mobilne_wybrane` ( `id_bazy` mediumint(1) UNSIGNED NOT NULL DEFAULT '0', `id_uzytkownika` mediumint(1) UNSIGNED NOT NULL DEFAULT '0', `priorytet` tinyint(1) UNSIGNED NOT NULL DEFAULT '0', `widoczne` tinyint(1) UNSIGNED NOT NULL DEFAULT '0', `nazwa` char(32) NOT NULL DEFAULT '' ) ENGINE=MyISAM DEFAULT CHARSET=latin2;
Ale niestety na bazie zawierającej odpowiednio rekordów:
mobilne_bazy - 72
mobilne_punkty - 2 577
mobilne_tmp_punkty - 7 172
mobilne_uzytkownicy - 526
mobilne_wybrane - 709
Wykonanie skryptu trwa wiecznie. W najlepszym przypadku kończy się po prawie minucie.
Moje pytania:
1. Jak trzy zapytania sklecić do jednego i czy to coś da?
2. Jak zbudować indeksy na bazie?
Udało mi się powyższe trzy zapytania zmieścić do dwóch:
SELECT p.id id, p.id_bazy id_bazy, p.x1 x1, p.x2 x2, p.x3 x3, p.y1 y1, p.y2 y2, p.y3 y3, p.nazwa nazwa, p.opis opis, w.nazwa nazwa_kategorii, w.priorytet priorytet, w.widoczne widoczne, b.odleglosc odleglosc FROM mobilne_wybrane w LEFT JOIN mobilne_punkty p ON (p.niewazny<3 AND p.id_bazy=w.id_bazy) LEFT JOIN mobilne_bazy b ON (b.id=w.id_bazy) WHERE w.id_uzytkownika='$UZYTKOWNIK'
i
SELECT id FROM mobilne_tmp_punkty WHERE id_uzytkownika='$UZYTKOWNIK' AND nazwa_kategorii='$punkt[nazwa_kategorii]' AND sqrt( pow( (x1+(x2*256)+(x3*256*256)) - ('$punkt[x1]'+('$punkt[x2]'*256)+('$punkt[x3]'*256*256)) , 2 ) + pow( (y1+(y2*256)+(y3*256*256)) - ('$punkt[y1]'+('$punkt[y2]'*256)+('$punkt[y3]'*256*256)) , 2 ) ) < '$punkt[odleglosc]'
Niestety ale zmniejszyło to tylko czas wykonywania skryptu może o kilka sekund.