MySQL fukcje porównywania tekstu
- 11-11-2006 00:53
MySQL fukcje porównywania tekstu
Cześć wszystkim,
Może ktoś z tutejszych grupowiczów znajdzie jakieś lekarstwo na opisaną przeze mnie bolączkę.
Na czym polega sprawa. Właśnie piszę sobie w MySQL procedurę do tworzenia statystyki słów w podanym tekście. Robiłam już to raz, ale było okropnie wolno, więc robię od nowa. Ale wcale nie jest lepiej. W skrócie całość przedstawia się tak: użytkownik wrzuca tekst, z którego SQL robi tablicę - liczy takie same słowa (np. "był") i w efekcie powstaje tablica, w której w jednej kolumnie mamy wszystkie unikalne formy a w drugiej ilość ich wystąpień. Do tej pory jest OK - tekst o długości 45000 słów (12000 unikalnych form) przerabia w 12 sekund. Teraz chodzi o to, żeby w tej tabeli formy odmienione zamienić na podstawowe ("był" na "być", "zielonym" na "zielony" etc.). I tu zaczynają się schody.
Mam w tym celu przygotowaną inną tablicę z zamieszczonymi wszystkimi formami jednego słowa - jedna komórka TEXT - wszystkie formy oddzielone spacjami, na samym początku forma podstawowa. Tabela ta jest wielka i nieporęczna (prawie 160 000 wierszy). Szukam przy pomocy LIKE %%, ale trwa to koszmarnie długo, podobnie MATCH AGAINST IN BOOLEAN MODE, zrobiłam też żeby każdą formę wsadzić do osobnej kolumny. Nic lepiej. W końcu wymyśliłam, żeby po prostu zrobić pary słów forma - podstawa, ale to też do bani, ilość wierszy urasta wówczas do 3 mln.
Czy ktoś z Was ma jakiś pomysł, jak się z tym uporać. Może niekoniecznie elegancki i "mały" - to ma działać tylko na lokalnym Apache'u. Chodzi o to, żeby było szybko.
Pozdrawiam,
J.
- 11-11-2006 00:53
A mam jeszcze związany z tym taki problem, w poniższej składni MySQL uparcie dostrzega błąd
UPDATE temp0 SET temp0.forma=(SELECT haslo2.podst FROM haslo2 WHERE MATCH (haslo2.has) AGAINST (temp0.forma IN BOOLEAN MODE) LIMIT 1)
Konkretnie chodzi o AGAINST. Awanturuje się, że incorrect argument. Czy ktoś spotkał się może z takim problemem??
Przemyslaw Popielarski - 11-11-2006 00:53
juanitka wrote: > Konkretnie chodzi o AGAINST. Awanturuje się, że incorrect argument. > Czy ktoś spotkał się może z takim problemem??
Dokumentacja sie spotkała. http://dev.mysql.com/doc/refman/5.0/...trictions.html "The argument to AGAINST() must be a constant string."
-- ../ premax ../ premax@hot.pl ../ koniec i bomba, a kto czytal ten traba. w.g.
Paweł Matejski - 11-11-2006 00:53
juanitka@vp.pl wrote: > Cześć wszystkim, > > W końcu wymyśliłam, żeby po prostu > zrobić pary słów forma - podstawa, ale to też do bani, ilość wierszy urasta > wówczas do 3 mln.
I to jest jedyna słuszna metoda. Co z tego, że ilość wierszy urasta do takiej wielkości - ilość danych jest ta sama. A SQL jest zrobiony do operowania na rekordach, nie na ciągach znaków. Czy takie złe wyniki miałeś z indeksem?
> Czy ktoś z Was ma jakiś pomysł, jak się z tym uporać. Może niekoniecznie > elegancki i "mały" - to ma działać tylko na lokalnym Apache'u. Chodzi o to, > żeby było szybko.
Co znaczy szybko?
Takie rzeczy robi się najszybciej jednak nie w bazach danych. Z tego co wiem to są jakieś dedykowane struktury, dzięki którym zmniejsza się rozmiar bazy i jednocześnie znacznie przyspiesza wyszukiwanie.
-- P.M.
- 11-11-2006 00:53
Użytkownik "Przemyslaw Popielarski" napisał w wiadomości > Dokumentacja sie spotkała. > http://dev.mysql.com/doc/refman/5.0/...trictions.html > "The argument to AGAINST() must be a constant string." >
No faktycznie, spotkała się ;-) czytałam i trąba jestem, ale z problemem już się uporałam, i to AGAINSTem mimo wszystko
Pozdro, j.
- 11-11-2006 00:53
Użytkownik "Paweł Matejski" napisał w wiadomości >> Cześć wszystkim,
> I to jest jedyna słuszna metoda. Co z tego, że ilość wierszy urasta do > takiej > wielkości - ilość danych jest ta sama. A SQL jest zrobiony do operowania > na > rekordach, nie na ciągach znaków. > Czy takie złe wyniki miałeś z indeksem?
Właśnie że nie ta sama, bo gdy się ustawi na parowanie formy podstawowej z każdą możliwą formą odmienioną, to ta podstawowa forma będzie skopiowana wielokrotnie, zupełnie bez sensu, np:
kot - kota kot - kotu kot - kotem
itd.
a niektóre z tych słów w bazie głównej mają ok. 150 form odmienionych - inne znów żadnej (np. "tak", "nie", "się"). Zupełny chaos, no, jak to w językach bywa - wiadomo. Indeksować próbowałam, ale nie na wiele się zdało.
W końcu jednak uporałam się z tym problemem - ostatecznie tekst o długości 45000 słów przerabiany jest w ok. 43 sekundy
> > Co znaczy szybko? >
To właśnie znaczy "szybko". Czyli, że nie chcę osiwieć zanim wyskoczy mi statystyka wyrazów, np. z całego Starego Testamentu.
> Takie rzeczy robi się najszybciej jednak nie w bazach danych.
Na pewno tak, ale ja dopiero zaczynam się bawić w praktyczne językoznawstwo korpusowe i jak na początek para php+sql idealna, tym bardziej, że jako tako sobie daję z tym radę. Początkowo próbowałam na samych tablicach w php, ale żopa - ok. 20x wolniej było i krztusił się ochydnie.
> Z tego co wiem to > są jakieś dedykowane struktury, dzięki którym zmniejsza się rozmiar bazy i > jednocześnie znacznie przyspiesza wyszukiwanie.
Są, są, na pewno istnieje taki sprytny algorytm pakowania wyjątkowo długich list słów, a wyniki są świetne, np na kurniku spakowali tym słownik do scrabble, zastosowanie czegoś w podobie na pewno jeszcze przyspieszyłoby działanie na takiej statystyce.
Pozdrawiam,
J.
Paweł Matejski - 11-11-2006 00:53
juanitka@vp.pl wrote: > Użytkownik "Paweł Matejski" napisał w wiadomości >> Cześć wszystkim, > >> I to jest jedyna słuszna metoda. Co z tego, że ilość wierszy urasta do >> takiej >> wielkości - ilość danych jest ta sama. A SQL jest zrobiony do operowania >> na >> rekordach, nie na ciągach znaków. >> Czy takie złe wyniki miałeś z indeksem? > > Właśnie że nie ta sama, bo gdy się ustawi na parowanie formy podstawowej z > każdą możliwą formą odmienioną, to ta podstawowa forma będzie skopiowana > wielokrotnie, zupełnie bez sensu, np: > > kot - kota > kot - kotu > kot - kotem > a niektóre z tych słów w bazie głównej mają ok. 150 form odmienionych - inne > znów żadnej (np. "tak", "nie", "się"). Zupełny chaos, no, jak to w językach > bywa - wiadomo.
No to możesz taką tabelę znormalizować i zamiast formy podstawowej dać id do tabeli z wyrazami. Przy indexie na kolumnie z odmianą powinieneś mieć odpowiedź prawie niezależną od ilości rekordów.
> Indeksować próbowałam, ale nie na wiele się zdało.
A mnie się zawsze wydawało, że na podobnej zasadzie działają indexy pełnotekstowe...
>> Co znaczy szybko? > > To właśnie znaczy "szybko". Czyli, że nie chcę osiwieć zanim wyskoczy mi > statystyka wyrazów, np. z całego Starego Testamentu.
No to trzeba tak od razu. Szybko jest pojęciem względnym.
>> Takie rzeczy robi się najszybciej jednak nie w bazach danych. > > Na pewno tak, ale ja dopiero zaczynam się bawić w praktyczne językoznawstwo > korpusowe i jak na początek para php+sql idealna, tym bardziej, że jako tako > sobie daję z tym radę. Początkowo próbowałam na samych tablicach w php, ale > żopa - ok. 20x wolniej było i krztusił się ochydnie.
No, php to się faktycznie do tego niespecjalnie nadaje.
-- P.M.
- 11-11-2006 00:53
Użytkownik "Paweł Matejski" <madej@spam.madej.pl.eu.org> napisał w wiadomości
> No to możesz taką tabelę znormalizować i zamiast formy podstawowej dać id > do > tabeli z wyrazami. Przy indexie na kolumnie z odmianą powinieneś mieć > odpowiedź > prawie niezależną od ilości rekordów.
No faktycznie, na to nie wpadłam, ale tutaj byłby problem z dodawaniem nowych rzeczy, np. gdyby się okazało, że trzeba uzupełnić odmianę, czy wtedy by się nie pokwasiło z AUTO_INCREMENT itp, na pewno by nie można było przenumerować bo by się wszystko pomyliło.
> No to trzeba tak od razu. Szybko jest pojęciem względnym.
A czas jest podobno tylko sposobem myślenia
Paweł Matejski - 11-11-2006 00:53
juanitka@vp.pl wrote: > Użytkownik "Paweł Matejski" <madej@spam.madej.pl.eu.org> napisał w > wiadomości > >> No to możesz taką tabelę znormalizować i zamiast formy podstawowej dać id >> do >> tabeli z wyrazami. Przy indexie na kolumnie z odmianą powinieneś mieć >> odpowiedź >> prawie niezależną od ilości rekordów. > > No faktycznie, na to nie wpadłam, ale tutaj byłby problem z dodawaniem > nowych rzeczy, np. gdyby się okazało, że trzeba uzupełnić odmianę, czy wtedy > by się nie pokwasiło z AUTO_INCREMENT itp, na pewno by nie można było > przenumerować bo by się wszystko pomyliło.
Nie, nie pokwasi się, jeśli zrobisz to zgodnie ze sztuką.
-- P.M.
zanotowane.pldoc.pisz.plpdf.pisz.pleffulla.pev.pl
|
[mysql] =?ISO-8859-2?Q?Za=E6mienie=2E=2E=2E_jak_wy=B6wietli=E6?==?ISO-8859-2?Q?=2E=2E=2E?=
[mysql] =?ISO-8859-2?Q?wielko=B6=E6_bazy_a_stabilno=B6=E6=2C?==?ISO-8859-2?Q?_podzia=B3_du=BFej_bazy_a_powi=B1zania_tabel?=
[MySQL] =?ISO-8859-2?Q?Wy=B6wietlenie_kolejnej_pozycji=2C_?==?ISO-8859-2?Q?jak=B1_mia=B3by_dany_rekord=2C_gdybym_czyta=B3 _?==?ISO-8859-2?Q?wg_konkretnych_kryteri=F3w=2E_Da_si=EA_=3F?=
[mysql 4.0.x] przenoszenie kolum =?ISO-8859-2?Q?mi=EAdzy_bazam?==?ISO-8859-2?Q?i_cd_=2E=2E=2E_?=
[MySQL] =?ISO-8859-2?Q?z=B3=B1czenie_tabeli_u=BFytkownik_i?==?ISO-8859-2?Q?_zdj=EAcia_z_wyborem_zdj=EAcia_domy=B6lnego?=
[MySQL] Jak =?ISO-8859-2?Q?wpisa=E6_do_tabeli_pozycje_dl?==?ISO-8859-2?Q?a_wierszy_gdybym_te_wiersze_wybiera=B3_w_ok?== ?ISO-8859-2?Q?re=B6lonej_kolejno=B6ci_=3F?=
Gdzie MySQL 4.1, a gdzie 5.0?
[MySQL 4.0...4.1] zabezpieczenie przed =?ISO-8859-2?Q?jednoczesn?==?ISO-8859-2?Q?=B1_edycj=B1?=
[MS SQL] "set names" (mySQL) w MS SQL
[mysql 5.x] jak =?ISO-8859-2?Q?zrealizowa=E6_zapytanie=3F_cz?==?ISO-8859-2?Q?yli_podzapytanie_i_wi=EAcej_ni=BF_jeden_rz=B1? ==?ISO-8859-2?Q?d_wynik=F3w?=
zanotowane.pldoc.pisz.plpdf.pisz.plbajkomoda.xlx.pl
Cytat
Decede mihi sole - nie zasłaniaj mi słonca. Gdy kogoś kochasz, jesteś jak stworzyciel świata - na cokolwiek spojrzysz, nabiera to kształtu, wypełnia się barwą, światłem. Powietrze przytula się do ciebie, choćby był mróz, a ty masz w sobie tyle radości, że musisz ją rozdawać wokoło, bo się w tobie nie mieści Hoc fac - tak czyń. A tergo - od tyłu; z tyłu. I czarne włosy posiwieją. Safona |
|