Foruma hoş geldin 👋, Ziyaretçi

Forum içeriğine ve tüm hizmetlerimize erişim sağlamak için foruma kayıt olmalı ya da giriş yapmalısınız. Foruma üye olmak tamamen ücretsizdir.

MySQL'de FULLTEXT Index Kullanımı ve Metin Tabanlı Arama Sorgularını Hızlandırma Yöntemleri

stackor

Üye
Katılım
14 Mart 2026
Mesajlar
20
Merhaba arkadaşlar, bugün sizlere özellikle forumlar, bloglar veya içerik yönetim sistemlerinde sıkça karşılaştığımız bir performans problemini ve onun kurşun geçirmez çözümünü anlatacağım: Metin aramalarını hızlandırmak. "LIKE '%aranan%'" sorguları tablonuz büyüdükçe sunucunuzu dizlerinin üzerine çökertebilir. Neyse ki MySQL'in içinde bu iş için özel olarak tasarlanmış çok güçlü bir silah var: FULLTEXT Index. Bu rehberde, bu indeksi nasıl oluşturacağımızı, nasıl kullanacağımızı ve ayarlarla nasıl ince ayar yapacağımızı adım adım işleyeceğiz.

🔍 FULLTEXT Index Nedir ve Ne Zaman Kullanılır?

FULLTEXT index, bir tablodaki metin sütunları (VARCHAR, TEXT) üzerinde, kelime bazlı hızlı arama yapabilmek için oluşturulan özel bir indeks türüdür. Geleneksel B-tree indeksler "LIKE 'kelime%'" gibi ön ek aramalarında iyidir, ancak "LIKE '%kelime%'" veya birden fazla kelime içeren karmaşık aramalarda tamamen etkisiz kalır. İşte tam bu noktada FULLTEXT devreye girer.

Benim sunucularda genelde, kullanıcı mesajlarının, makale içeriklerinin veya ürün açıklamalarının arandığı her yerde bu yönteme başvururum. Performans farkı inanılmazdır.

⚙️ FULLTEXT Index Oluşturma ve Temel Kullanım

Öncelikle, üzerinde arama yapmak istediğimiz bir tablomuz ve sütunumuz olduğunu varsayalım. Diyelim ki `makaleler` adında bir tablomuz ve `baslik` ile `icerik` alanlarında arama yapmak istiyoruz.

İlk adım, mevcut tablomuza bir FULLTEXT indeksi eklemek. Şu ayara çok dikkat etmelisiniz: InnoDB motoru için MySQL 5.6 ve sonrası FULLTEXT'i destekler. Eski MyISAM tablolarında da çalışır ama InnoDB kullanmanızı şiddetle tavsiye ederim.

SQL:
-- Mevcut bir tabloya FULLTEXT indeksi ekleme
ALTER TABLE makaleler ADD FULLTEXT INDEX `ft_idx_baslik_icerik` (`baslik`, `icerik`);

-- Veya tablo oluştururken ekleyebilirsiniz.
CREATE TABLE makaleler (
    id INT AUTO_INCREMENT PRIMARY KEY,
    baslik VARCHAR(255),
    icerik TEXT,
    FULLTEXT INDEX `ft_idx_baslik_icerik` (`baslik`, `icerik`)
);

İndeksi oluşturduk. Peki nasıl arama yapacağız? `MATCH() ... AGAINST()` yapısını kullanacağız.

SQL:
-- Doğal dil modunda basit arama
SELECT  FROM makaleler
WHERE MATCH(baslik, icerik) AGAINST('veritabanı optimizasyonu' IN NATURAL LANGUAGE MODE);

Bu sorgu, `baslik` ve `icerik` alanlarında "veritabanı" ve "optimizasyonu" kelimelerini içeren ve bu kelimelere göre bir ilgi puanı (relevance score) hesaplanmış kayıtları getirecektir. Sıralama yapmak isterseniz:

SQL:
SELECT id, baslik,
    MATCH(baslik, icerik) AGAINST('veritabanı optimizasyonu') AS puan
FROM makaleler
WHERE MATCH(baslik, icerik) AGAINST('veritabanı optimizasyonu')
ORDER BY puan DESC;

⚡ İleri Seviye: Boolean Modu ve Stopwords

Doğal dil modu güzel ama bazen daha fazla kontrol istersiniz. Örneğin, bir kelimenin kesinlikle olmasını (+), olmamasını (-) veya alt sorguları () belirlemek isteyebilirsiniz. Boolean mod tam size göre.

SQL:
-- "optimizasyonu" kelimesi geçsin, "yavaş" kelimesi geçmesin, "MySQL" kelimesi önemli olsun.
SELECT  FROM makaleler
WHERE MATCH(baslik, icerik) AGAINST('+optimizasyonu -yavaş MySQL' IN BOOLEAN MODE);

Bir diğer kritik konu da "stopwords" yani dilde sık geçtiği için indekslenmeyen kelimeler (ve, veya, bir, gibi). MySQL'in varsayılan bir stopword listesi vardır. Eğer aramalarınızda bu kelimeler önemliyse (örneğin, "ve" bağlacı bir marka adının parçası olabilir), listeyi yönetebilirsiniz. Dosya yolu /usr/share/mysql/stopwords.txt (veya information_schema.INNODB_FT_DEFAULT_STOPWORD) olabilir. Değişiklik yapmak ciddi bir iştir, test ortamında denemeden production'a sürmeyin.

⚠️ Dikkat Edilmesi Gerekenler ve Optimizasyon İpuçları

1. İndeks Boyutu: FULLTEXT indeksleri, özellikle büyük TEXT alanları üzerinde oluşturulduğunda oldukça büyük yer kaplayabilir. Disk alanınızı gözden geçirin.
2. Minimum Kelime Uzunluğu: Varsayılan olarak, 3 veya 4 karakterden kısa kelimeler indekslenmez (`ft_min_word_len` veya `innodb_ft_min_token_size` ayarı). Bu, "ve", "için" gibi kelimelerin aranmaması anlamına gelir. Bu ayarı değiştirirseniz, indeksi yeniden oluşturmanız (REBUILD) gerekir!
INI:
# my.cnf veya my.ini dosyasında
    [mysqld]
    innodb_ft_min_token_size = 2
    ft_min_word_len = 2
Ayarları değiştirdikten sonra:
SQL:
ALTER TABLE makaleler DROP INDEX ft_idx_baslik_icerik;
    ALTER TABLE makaleler ADD FULLTEXT INDEX ft_idx_baslik_icerik (baslik, icerik);
3. Sorgu Performansı: `MATCH()` fonksiyonunun içinde indeks tanımlarken kullandığınız sütunların aynı sırada ve hepsini yazın. Aksi takdirde indeks kullanılmaz.
4. MyISAM vs InnoDB: Mümkünse InnoDB kullanın. MyISAM, tablo seviyesinde kilitler ve büyük ölçekli sistemlerde sorun çıkarabilir.

🎯 Sonuç ve Öneriler

FULLTEXT index, metin aramalarından mustarip olan her uygulama için bir game-changer'dır. Doğru şekilde uygulandığında, saniyeler süren sorguları milisaniyelere indirebilir. Başlangıçta doğal dil modu ile başlayıp, ihtiyaçlarınız arttıkça Boolean modunun gücünden faydalanabilirsiniz.

Ben genelde, büyük metin alanları için ayrı bir FULLTEXT indeks, başlık gibi kısa alanlar için ise ayrı bir indeks oluşturmayı tercih ederim. Bu, sorgu performansını daha da optimize edebilir.

Peki siz bu konfigürasyonu kendi sunucularınızda nasıl yapıyorsunuz? FULLTEXT ile ilgili yaşadığınız ilginç performans hikayeleriniz veya takıldığınız noktalar var mı? Aşağıya yorum olarak yazarsanız, topluluk olarak çözüm bulabiliriz. Sağlıcakla kalın, kodunuz bol olsun!
 

Tema özelleştirme sistemi

Bu menüden forum temasının bazı alanlarını kendinize özel olarak düzenleye bilirsiniz.

Zevkine göre renk kombinasyonunu belirle

Tam ekran yada dar ekran

Temanızın gövde büyüklüğünü sevkiniz, ihtiyacınıza göre dar yada geniş olarak kulana bilirsiniz.

Geri