SQL - sprawdzenie czy dany rekord istnieje.

0

Cześć.
Szukam najbardziej wydajnego zapytania, które sprawdza czy rekord o danym tytule istnieje w bazie danych MYSQL.
Mam trzy:
1.
SELECT 1 FROM Releases WHERE TITLE='" + title + "';

SELECT count(1) FROM Releases WHERE TITLE='" + title + "';

SELECT TITLE FROM Releases WHERE TITLE='" + title + "';

Pozdrawiam.

0

if exists(SELECT 1 FROM tablica WHERE TITLE='" + title + "')

Wywala error:
Incorrect syntax near ')'

1

Ten tytuł to taki przykład przykładowy czy realne pytanie?
Bo jeśli realne to raczej bezużyteczne - chociaż tego nie widać.

  1. Wersja dla scenariusza "naprawdę chodzi o tytuł"

W tym scenariuszu szukany tytuł jest podawany przez użytkownika i nie wiadomo do końca co on tam poda.
Dlatego trzeba ustandaryzować tekst przed wyszukaniem (i przed zapisem do pola - w ten sam sposób):

  • skompresować spacje wewnętrzne (5 spacji -> 1 spacja)
  • obciąć spacje na początku i na końcu
  • zamienić wszystkie litery np. na małe (albo zastosować COLLATE z stroną *_ci)

http://dev.mysql.com/doc/refman/5.0/en/case-sensitivity.html

A potem użyć np. like + limit :
SELECT 1 FROM Releases WHERE TITLE like '%" + title + "%' LIMIT 0, 1;

Lub count(1) + like:

SELECT count(1) FROM Releases WHERE TITLE like '%" + title + "%';

To jest zapytanie nie indeksowane (wolne) - w każdej wersji. No chyba że zakładasz że użytkownik podał na pewno dobry początek - wtedy zakładasz indeks na polu TITLE i
nie używasz pierwszego procenta.

Żeby wykorzystać indeks w takim zapytaniu możesz też użyć "Full Text Search":
http://dev.mysql.com/doc/refman/5.0/en/fulltext-search.html

  1. Wersja dla scenariusza "mam wartość primary key"

SELECT 1 FROM Releases WHERE id = " + id + ";

Najbardziej optymalna - o ile masz dostępną wartość unikalnego pola w tabeli (i masz na nim indeks - najlepiej PK).

0

Dzięki za wskazówki (szczególnie za LIMIT, które musiałem zamienić na TOP). Input "użytkownika" (który nie jest człowiekiem :P) zawsze będzie dobrze sformatowany, więc nie muszę nic tam obrabiać.
Teraz zapytanie wygląda tak:
select top 1 1 from tablica where TITLE = 'Dupa'
Średnio zostaje wykonane w 0.0312 sekundy.
To, które miałem na początku:
select 1 from Dragon.dbo.Releases where TITLE = 'Dupa'
Średnio zostaje wykonane w 0.1248 sekundy, czyli 4 razy wolniej, bo musiało przejść przez wszystkie rekordy... W tych zapytaniach szukałem tytułu, który jest w bazie danych. W bazie mam 314000 rekordów.

Jak założę PK na TITLE (każdy rekord ma inny tytuł, nie ma duplikatów), to powinno być jeszcze szybciej?
Jak ktoś ma inne pomysły, to czekam.

0
carck3r napisał(a):

Jak założę PK na TITLE (każdy rekord ma inny tytuł, nie ma duplikatów), to powinno być jeszcze szybciej?
Jak ktoś ma inne pomysły, to czekam.

Wystarczy indeks, najlepiej unikalny - jeśli możesz.
Jesteś pewien że nie ma duplikatów na tytule? I że się nie zdarzą?

0
vpiotr napisał(a):
carck3r napisał(a):

Jak założę PK na TITLE (każdy rekord ma inny tytuł, nie ma duplikatów), to powinno być jeszcze szybciej?
Jak ktoś ma inne pomysły, to czekam.

Wystarczy indeks, najlepiej unikalny - jeśli możesz.
Jesteś pewien że nie ma duplikatów na tytule? I że się nie zdarzą?

Nie mam duplikatów i nie będę miał.
Rozumiem, że wystarczy kliknąć prawym w SSMS w design na kolumnę TITLE w mojej tablicy, wybrać indexes..., Add i zmienić na coś takiego, tak?
user image
Od teraz będę miał indeks na TITLE? Nie widzę wzrostu wydajności (cały czas 0.3xxx). Tak czy siak jest szybciej i nie obciąża tak procesora jak na początku.

1 użytkowników online, w tym zalogowanych: 0, gości: 1