piątek, 14 czerwca 2013

Drugi komunikat z trasy

Od kilku dni wszystko jest na linuxpl - udało mi się przenieść rozwiązania z MS-SQL-a na MySQL. Nauczyłem się, czego MySQL nie znosi, na czym się wywala, czym się różni składnia tej wersji języka od składni ogólnej. Najbardziej brakowało mi tego, że w MySQL-u nie ma w ogóle funkcji tabelarycznych (czyli funkcji, które zwracałyby nie pojedyncze wartości, lecz cały zestaw rekordów (z angielska nazywa się to DataSet). Brak takich funkcji zmuszał mnie do odwoływania się do tabel stałych, co po pierwsze jest znacznie wolniejsze, a po drugie wymaga odróżniania rekordów moich od nie moich... No ale najważniejsze, że wszystko jest i że działa!

Niestety nie działa tak, jak bym chciał - działa za wolno!

Pozostawiłem to, co napisałem na początek, ale dodałem dodatkowo wywołanie tej nowej procedury. Okazuje się, że ten nowy licznik gubi rekordy - i to różnice są znaczne. Np. dziś do tej pory nowy licznik odnotował 396 odwiedzin, gdy w tym samym czasie stary odnotował ich 513! A więc nawet to nie są pojedyncze rekordy, lecz 1/5 wszystkich rekordów!
MySQL nie ma takich narzędzi diagnozy, jakimi dysponuje MS-SQL, a ja nawet nie próbowałem prostych porównań z selektów z obu tabel, ale podejrzewam, że to jest tak, że jeśli ktoś wejdzie na stronę, zanim skończy się zapis rekordów poprzedniego wejścia, to te wcześniejsze wejście już nie zostanie w ogóle zapisane. Innymi słowy jest tak, że póki nie uda mi się skrócić czasu potrzebnego do zapisania rekordu odwiedzin, to mój nowy licznik do niczego się nie nadaje!

Pierwsze zmiany już wprowadziłem, ale te różnice, jakie podałem, są już po zastosowaniu tych zmian - potrzebne są dalsze. Najbliższy krok będzie polegał na zmniejszeniu liczby zapytań SQL-owych wywoływanych ze skryptu PHP. W tej chwili są aż 4 takie wywołania - zadeklarowanie zmiennych, wywołanie procedury rozpoznającej bloga, pobranie tych zmiennych ustawionych przez procedurę i dopiero jako czwarte jest wywołanie właściwej procedury. Przesunę wywołanie tej procedury rozpoznającej bloga do środka właściwej procedury, a w tej sposób skrypt PHP. Mam nadzieję, że to wystarczy, ale w zanadrzu mam jeszcze kilka pomysłów. 

W każdym razie jeszcze to potrwa...

niedziela, 2 czerwca 2013

Komunikat z trasy

Mój plan pisania licznika był następujący:

  • założyć tabelę na MySQL-u zbierającą dane o odsłonach i napisać skrypt PHP, który byłby uruchamiany z blogów z zainstalowanym licznikiem,
  • importować dane z tej tabeli na MySQL na MS-SQL i napisać procedurę dodającą jeden rekord odsłony, która byłaby wywoływana w kursorze (czyli rekord po rekordzie). Język SQL (Structured Query Language) jest językiem zbiorów - zapytania pisze się od razu dla wszystkich rekordów naraz; tym razem takie podejście byłoby jednak błędne, bo przecież każda odsłona uruchamia skrypt PHP, a więc w działającym liczniku rekordy będą dodawane rekord po rekordzie i procedura musi być testowana w takich samych warunkach,
  • modyfikować tę procedurę i powtarzać jej wywołanie na pustej bazie na zasadzie rekord po rekordzie, sprawdzając przy tym wynik działania tej procedury,
  • po uznaniu, że procedura dosyć dobrze sobie radzi, przenieść całą strukturę bazy (wszystkie tabele docelowe, jak np. tabela komputerów, przeglądarek internetowych komputera itp) na MySQL oraz przetłumaczyć procedurę z języka MS-SQL na język MySQL. 
Ten ostatni krok o tyle zmodyfikowałem, że uznałem, iż nigdy algorytm nie będzie na tyle dobry, by nie wprowadzał błędów. Dopisałem więc jeszcze procedury łączące ze sobą wskazane komputery w jeden komputer oraz procedurę odwrotną - z tego, co zostało uznane jako wejścia z jednego komputera, wydzielające nowy komputer, do którego przypisane by były wskazane odsłony. Obie procedury sprawdzają przy tym wiele rzeczy, by wychwycić ewentualne błędy operatora (bo np. wszystkie odsłony ponad wszelką wątpliwość pochodziły z jednego komputera - a więc w takiej sytuacji wydzielanie odrębnego komputera nie miałoby sensu).
Do tego etapu właśnie doszedłem, a przede mną było jeszcze:

  • opanowanie techniki zwracania przez skrypt PHP obrazka z danymi (ile aktualnie jest osób, ile było od początku dnia, ile wczoraj, ile od założenia licznika,
  • opracowania strony, na której każdy mógłby zarejestrować swój licznik,
  • opracowanie strony, na której można by było oglądać i modyfikować (nazywanie komputerów + owo łączenie komputerów i ich oddzielanie) dane źródłowe dotyczące statystyk, 
  • opracowanie strony, na której można by było oglądać statystyki swojego bloga,
  • opracować skrypty eksportu danych dotyczących swojego licznika.
Niestety w tym miejscu, do którego doszedłem, napotkałem na nieprzewidzianą trudność - okazuje się, że nie mam uprawnień do zakładania procedur (mogę jedynie tabele). Nie dość że samo tłumaczenie kodu MS-SQL na MySQL okazało się znacznie trudniejsze, niż pierwotnie przypuszczałem (język MySQL jest znacznie uboższy - np. nie ma funkcji tabelarycznych, a i sposób zapisu znacznie się różni), to na dodatek wykreowana przeze mnie procedura jest niedostępna - po prostu znika. Znalazłem zmienną globalną, którą na MySQL-u powinienem przestawić, ale do jej przestawienia również nie mam praw!

Tak więc oddanie wam, jako potencjalnym zainteresowanym, moich liczników opóźnia się. Mam dwie drogi, ale nie wiem, czy którakolwiek okaże się skuteczna - albo uda mi się dowiedzieć, jak sam sobie mogę nadać większe uprawnienia (ale być może takiej możliwości nie ma - być może to jest w gestii adminów linuxpl, a oni ich nie nadają w trosce o własny serwer), albo w miejsce procedury MySQL napisać bardzo rozbudowany skrypt PHP - cała logika jest zawarta w obecnej procedurze na MS-SQL i tylko trzeba by było napisać ją w zupełnie innym języku.
Jak więc widać, utonąłem w licznikach i zupełnie nie wiem, kiedy z nich wypłynę (o ile wypłynę, bo być może będę mógł pozostać jedynie przy ofercie dla zaprzyjaźnionych blogerów, których wyniki opracowywałbym ręcznie na każde żądanie w postaci plików excelowych - to mogę zaoferować już dziś).