Tüm Ürünler
Search
Belge Merkezi

Lindorm:Lindorm SQL SSS

Son Güncelleme:Oct 07, 2026

LindormTable (geniş tablo motoru) ile Lindorm SQL kullanırken karşılaşılan yaygın sorunlar ve çözümleri.

Not

Bu sayfadaki tüm sorunlar yalnızca LindormTable için geçerlidir.

Sorgu sorunları

  • S: Verimsiz sorguları nasıl çözer veya önlerim?

    C: Sorgunuz This query may be a full table scan and thus may have unpredictable performance hatasını döndürüyorsa bu sorgu verimsiz kabul edilir.

    Verimsiz sorgu nedir? LindormTable'da filtre koşullarının birincil anahtarı veya mevcut bir dizini etkili şekilde kullanamadığı sorgular tam tablo taramasına zorlanır. Bu tür sorgular verimsiz kabul edilir. LindormTable veritabanı performansını ve kararlılığını korumak için bunları varsayılan olarak engeller.

    Eşleşme kuralları MySQL'in bileşik dizinler için kullandığı en sol önek kuralını izler. Sistem WHERE yan tümcesindeki sütunları en soldaki sütundan başlayarak birincil anahtar (veya dizin anahtarı) sütunlarıyla eşleştirir. Sorgunuz ilk sütunu atlarsa anahtar kullanılmaz ve tam tablo taraması gerçekleşir.

    Örneğin test tablosunda bileşik birincil anahtar (p1, p2, p3) varsa ve aşağıdaki komutu çalıştırırsanız:

    SELECT * FROM test WHERE p2 < 30;

    Sorgu p1 sütununu atladığı için LindormTable birincil anahtarı kullanamaz. p2 < 30 koşulunu karşılamak üzere tüm tablo taranır.

    Bunu düzeltmek veya önlemek için:

    • En sol önek kuralına uyarak WHERE yan tümcesine birincil anahtarın ilk sütununu ekleyin.

    • Tablonun birincil anahtarını yeniden tasarlayın. Bkz. Geniş tablo için birincil anahtar nasıl tasarlanır.

    • Sorguladığınız sütunlarda ikincil dizin oluşturun. Bkz. İkincil dizinler.

    • Birden çok sütunda çok boyutlu sorgular için arama dizini oluşturun. Bkz. Arama dizinleri.

    • Verimsiz sorgunun çalıştırılmasını zorlamak için /*+ _l_allow_filtering_ */ ipucunu ekleyin:

      SELECT /*+ _l_allow_filtering_ */ * FROM dt WHERE nonPK = 100;
    Önemli

    Tam tablo taramasını zorlamak genel veritabanı performansını ve kararlılığını düşürme riski taşır. Bu yaklaşımı yalnızca etkiyi değerlendirdikten sonra kullanın.

  • S: GROUP BY sorgusu neden "subPlan groupby keys" hatasıyla başarısız olur?

    C: Hata mesajı:

    The diff group keys of subPlan is over lindorm.aggregate.subplan.groupby.keys.limit=..., it may cost a lot memory so we shutdown this SubPlan

    GROUP BY işlemi çok fazla grup üretmiştir. Çok sayıda grup aşırı bellek tüketir ve örnek yükünü artırır; bu nedenle LindormTable alt planı kapatır.

    Bunu çözmek için:

    • Toplamadan önce grup sayısını azaltmak için filtre koşulları ekleyin.

    • Çok boyutlu toplama senaryolarında iş yükünü hafifletmek için arama dizini oluşturun. Bkz. Arama dizinleri.

    • Grup sayısı eşik değerini artırmak için Lindorm teknik desteğiyle iletişime geçin (DingTalk Kimliği: s0s3eg3).

    Önemli

    Grup sayısı eşik değerini yükseltmek bellek tüketimini artırır ve örnek kararlılığını etkileyebilir. Değişiklik yapmadan önce etkiyi değerlendirin.

  • **S: Dinamik sütunlu bir tabloda SELECT * neden "Limit not set" hatasıyla başarısız olur?**

    C: Hata mesajı:

    Limit of this select statement is not set or exceeds config when select all columns from table with property DYNAMIC_COLUMNS=true

    Dinamik sütunlu tablolar sabit bir şemaya sahip değildir ve büyük öngörülemez sayıda sütun içerebilir. Satır sınırı olmadan SELECT * çalıştırmak yüksek G/Ç yüküne ve örnek yükünün artmasına neden olur; bu nedenle LindormTable bu tür sorgularda LIMIT yan tümcesi gerektirir.

    SELECT ifadesine LIMIT yan tümcesi ekleyin:

    SELECT * FROM test LIMIT 10;
  • S: Bir sorgu neden "Code grows beyond 64 KB" hatasıyla başarısız olur?

    C: Lindorm SQL altyapısı Just-In-Time (JIT) derlemesi kullanır: Sorgunun fiziksel planından bytecode oluşturur ve bunu çalışma zamanında derler. Bu hata oluşturulan bir yöntem için bytecode'un Java Sanal Makinesi (JVM) tarafından dayatılan 64 KB sınırını aştığı anlamına gelir.

    En yaygın neden SQL sorgu ifadesindeki koşulun çok uzun veya karmaşık olmasıdır; bu durum yürütülemeyecek kadar büyük bytecode oluşmasına yol açar.

    SQL ifadesindeki koşul ifadelerini basitleştirin. Karmaşık koşulları daha küçük parçalara bölün veya bytecode boyutunu azaltmak için mantığı yeniden yazın.

  • S: Bir sorgu neden "The estimated memory used by the query exceeds the maximum limit" hatasıyla başarısız olur?

    C: SQL altyapısı sonuç kümelerini işlerken (toplama sıralama veya yinelenen kayıtları kaldırma sırasında) önemli miktarda bellek tüketir. Lindorm SQL yüksek eşzamanlılık gerektiren çevrimiçi iş yükleri için tasarlandığından varsayılan olarak her sorguyu 8 MB bellekle sınırlar. Bu sınırı aşmak bellek taşması istisnasına neden olur.

    1. Adım — Harekete geçmeden önce teşhis edin:

    Toplama ve sıralama operatörlerinin depolama altyapısına mı yoksa SQL altyapısında mı yürütüldüğünü belirlemek için yürütme planını kontrol edin. Bkz. Yürütme planını yorumlama.

    • Yoğun operatörler SQL altyapısında çalışıyorsa doğru çözüm sorgu optimizasyonudur (bkz. Seçenek 1).

    • Operatörler zaten aktarılmışsa ve sorgu zaten optimize edilmişse bellek sınırını yükseltin (bkz. Seçenek 2).

    Seçenek 1 — Sorguyu optimize edin (tercih edilen):

    Dizinleri kullanarak toplama ve sıralamayı depolama altyapısına aktarın ve SQL altyapısının işlediği veri miktarını azaltmak için filtre koşullarını sıkılaştırın.

    Seçenek 2 — Bellek sınırını yükseltin:

    Sorgu zaten optimize edilmişse ve daha yüksek bir sınıra ihtiyacınız varsa ALTER SYSTEM kullanarak QUERY_MAX_MEM değerini ayarlayın:

    ALTER SYSTEM SET QUERY_MAX_MEM = 8388608;

    Mevcut değeri SHOW VARIABLES ifadesiyle kontrol edin.

    SQL altyapı sürümünüz 2.9.6.0'dan önceyse limiti artırmak için Lindorm teknik desteğiyle (DingTalk Kimliği: s0s3eg3) iletişime geçin.

    Önemli

    Yüksek eşzamanlılık ortamlarında QUERY_MAX_MEM değerini yükseltmek kümedeki bellek baskısını artırır ve zorunlu Tam GC'yi tetikleyerek tüm kümenin yanıt verebilirliğini düşürebilir. Bu değeri artırmadan önce sorgu aktarım hızını ve eşzamanlılığı dikkatlice değerlendirin.

  • **S: Tek bir WHERE yan tümcesinde birçok IS NULL koşulu kullanılması neden önerilmez?**

    C: LindormTable'da IS NULL hem "sütun NULL değerle mevcuttur" hem de "sütun mevcut değil veya hiç yazılmamış" durumlarını işlemelidir. Bir SQL ifadesi birden çok IS NULL koşulu içerdiğinde SQL altyapısı derleme sırasında bu koşulları kombinasyonlara genişletebilir. N adet IS NULL koşulu teorik olarak 2^N dala kadar üretebilir; bu durum derleme süresini ve bellek kullanımını önemli ölçüde artırır. Ağır vakalarda bu durum sorgu yürütmeyi ve örnek kararlılığını etkileyebilir.

    Öneri: Tek bir SELECT UPDATE veya DELETE ifadesinde birçok column IS NULL koşulunu birleştirmekten kaçının. Aşağıdaki yaklaşımları düşünün:

    • Mümkün olduğunca birincil anahtarları ikincil dizinleri veya arama dizinlerini kullanarak sorgu aralığını daraltın.

    • İş mantığınız alanların boş olup olmadığını veya mevcut olup olmadığını sıkça kontrol ediyorsa bu iş durumunu yazma tarafında açıkça ifade edin; örneğin varsayılan değerler veya durum sütunları kullanın.

    • Toplu işleme için işi daha basit koşullara sahip birden çok SQL ifadesine bölün veya önce tam birincil anahtarları getirip bunları birincil anahtara göre toplu olarak işleyin.

  • S: WHERE yan tümcesinde AND ile birleştirilmiş birçok OR grubu kullanılması neden önerilmez?

    Sorun: WHERE yan tümcesinin parantez içindeki OR gruplarını AND ile bağladığı bir SQL ifadesi örneğin:

    SELECT * FROM orders
    WHERE (status = 1 OR status = 2)
      AND (pay_type = 'wechat' OR pay_type = 'alipay')
      AND (region = 'CN' OR region = 'US')
      AND ...;

    İç içe geçme derinliği arttıkça risk de artar. Bu durum SELECT UPDATE ve DELETE ifadeleri için aynı şekilde geçerlidir.

    C: Optimizer her bağımsız koşul için optimal dizin erişim yolunu seçebilmesi amacıyla sorguyu yürütmeden önce WHERE yan tümcesini Dağıtılmış Normal Forma (DNF) — yani AND koşullarının OR kümesine — dönüştürmelidir. Optimizer (A OR B) AND (C OR D) yapısıyla karşılaştığında bunu genişletmek için dağıtma yasasını uygulamalıdır:

    (A∨B)∧(C∨D) ⇒ (A∧C)∨(A∧D)∨(B∧C)∨(B∧D)

    (A or B) and (C or D) ⇒ (A and C) or (A and D) or (B and C) or (B and D)

    • Her biri 2 dallı 2 grup: 2×2 = 4 kombinasyon terimi.

    • Her biri 2 dallı 3 grup: 2×2×2 = 8 kombinasyon terimi.

    Grup sayısı ve grup başına dal sayısı arttıkça kombinasyon terimlerinin sayısı üstel olarak artar. Bu durum optimizer derleme süresini ve bellek kullanımını önemli ölçüde artırabilir; ağır vakalarda sorgu yürütmeyi ve örnek kararlılığını etkileyebilir.

    Öneri:

    • Tek bir SQL ifadesinde AND ile birleştirilmiş birçok parantezli OR grubu kullanmaktan kaçının.

    • Aynı sütuna yönelik OR koşullarını IN ile yeniden yazın — örneğin status IN (1, 2) — böylece genişletilen dal sayısını azaltın.

    • Mümkün olduğunca birincil anahtarları ikincil dizinleri veya arama dizinlerini kullanarak sorgu aralığını daraltın.

    • Çok boyutlu eşleştirme senaryoları için arama dizini kullanın. Bkz. Arama dizinleri.

    • İş mantığı karmaşık koşullar gerektiriyorsa işi daha basit birden çok SQL ifadesine bölün veya önce tam birincil anahtarları getirip bunları birincil anahtara göre toplu olarak işleyin.

  • S: Belirli bir sorgu için bellek sınırı hatasını nasıl teşhis eder ve çözerim?

    C: Bir sorgu bellek sınırı hatasıyla başarısız olduğunda kök nedeni teşhis etmek ve uygun çözümü seçmek için şu adımları izleyin:

    1. Adım — Yürütme planını kontrol edin:

    Başarısız olan sorguda EXPLAIN çalıştırarak yürütme planını görüntüleyin. Ayrıntılar için bkz. Yürütme planını yorumlama.

    Yürütme planında toplama sıralama ve yinelenen kayıtları kaldırma gibi bellek yoğun operatörlerin SQL altyapısında mı yoksa depolama altyapısına mı aktarıldığını belirleyin. SQL altyapısında çalışan operatörler sorgu başına bellek sınırından bellek tüketirken aktarılan operatörler bunun yerine depolama altyapısı kaynaklarını kullanır.

    2. Adım — Sorguyu optimize etmeyi deneyin:

    Bellek yoğun operatörler SQL altyapısında çalışıyorsa bellek tüketimini azaltmak için aşağıdaki yaklaşımları deneyin:

    • Toplama operatörleri için (GROUP BY, COUNT, SUM, AVG): Gruplanan veya toplanan sütunlarda operatörün depolama altyapısına aktarılmasını sağlamak üzere ikincil dizin veya arama dizini oluşturun.

    • Sıralama operatörleri için (ORDER BY): Bellek içi sıralamadan kaçınmak için sıralama sütunlarının mevcut bir dizinle hizalandığından emin olun. Alternatif olarak sıralamadan önce veri kümesi boyutunu azaltmak için daha sıkı WHERE koşulları ekleyin.

    • Yinelenen kayıtları kaldırma operatörleri için (DISTINCT): Yüksek kardinaliteli sütunlardaki sorgular için arama dizini kullanın veya işlenen satır sayısını azaltmak için seçici filtre koşulları ekleyin.

    3. Adım — Gerekirse bellek sınırını yükseltin:

    Tüm operatörler zaten aktarılmışsa ve sorgu daha fazla optimize edilemiyorsa ALTER SYSTEM kullanarak QUERY_MAX_MEM değerini yükseltin:

    ALTER SYSTEM SET QUERY_MAX_MEM = <new_value_in_bytes>;

    Mevcut değeri SHOW VARIABLES ifadesiyle kontrol edin.

    Önemli

    Yüksek eşzamanlılık ortamlarında daha yüksek bir QUERY_MAX_MEM değeri genel küme bellek baskısını artırır ve zorunlu Tam GC'yi tetikleyerek tüm kümenin yanıt verebilirliğini düşürebilir. Bu değeri değiştirmeden önce sorgu aktarım hızınızı ve eşzamanlılığınızı değerlendirin.

Dizin ve şema sorunları

  • S: İkincil dizin oluşturma neden "Executing job number exceed, max job number = 8" hatasıyla başarısız olur?

    C: Her Lindorm örneği en fazla 8 eşzamanlı ikincil dizin oluşturma görevine izin verir. 8 görev zaten çalışıyorsa yeni dizin oluşturma girişimleri başarısız olur.

    Aynı anda çok sayıda ikincil dizin oluşturmaktan kaçının. Çok sayıda dizini toplu olarak oluşturmanız gerekiyorsa Lindorm teknik desteğiyle (DingTalk Kimliği: s0s3eg3) iletişime geçin.

  • S: Bir sütunu silindikten sonra aynı adla sütun ekleme neden "column is under deleting" hatasıyla başarısız olur?

    C: Bir sütunu sildikten sonra LindormTable sütunun verilerini bellekten sıcak depolamadan ve soğuk depolamadan eşzamansız olarak temizler. Sistem tür uyumsuzlukları veya veri çakışmalarından kaynaklanan kirli verileri önlemek amacıyla temizleme tamamlanana kadar aynı ada sahip bir sütunun yeniden eklenmesini engeller.

    Temizleme arka planda çalışır ve uzun sürebilir. Hızlandırmak için tabloda aşağıdaki ifadeleri çalıştırın (dt yerine kendi tablo adınızı yazın):

    -- Flush residual in-memory data to storage.
    ALTER TABLE dt FLUSH;
    
    -- Run compaction to merge and remove deleted data.
    ALTER TABLE dt COMPACT;

    Temizleme tamamlandıktan sonra sütunu yeniden ekleyin.

    Önemli
    • FLUSH SQL altyapı sürüm 2.7.1'den itibaren desteklenir. Sürümünüzü SQL sürüm kılavuzunda kontrol edin.

    • Hem FLUSH hem de COMPACT eşzamansızdır. İfadenin başarılı yürütülmesi temizlemenin tamamlandığı anlamına gelmez.

    • Büyük veri hacmine sahip bir tabloda COMPACT çalıştırmak önemli sistem kaynakları tüketir. Yoğun iş saatlerinde çalıştırmaktan kaçının.

  • S: İkincil dizin oluşturduktan sonra veri yazma neden "User-Defined-Timestamp" hatasıyla başarısız olur?

    C: Hata mesajı:

    Performing put operations with User-Defined-Timestamp in indexed column on MULTABLE_LATEST table is unsupported

    Açık özel zaman damgasıyla veri yazdığınızda — örneğin bir UPSERT ifadesinde /*+ _l_ts */ ipucunu kullanarak — hem birincil tablo hem de ikincil dizin tablosunun değiştirilebilirliğinin MUTABLE_ALL olarak ayarlanması gerekir. Ancak Lindorm performans nedenleriyle yeni tabloları ve dizinleri varsayılan olarak MUTABLE_LATEST olarak ayarlar. MUTABLE_LATEST değiştirilebilirliğine sahip bir dizin tablosuna özel zaman damgasıyla yazmak bu hatayı tetikler.

    MUTABILITY özelliği bir dizin tablosu oluşturulduktan sonra değiştirilemez. Mevcut dizini silmeniz birincil tablonun değiştirilebilirliğini güncellemeniz ve ardından dizini yeniden oluşturmanız gerekir.

    1. Mevcut ikincil dizini devre dışı bırakın ve silin:

      -- Disable the index.
      ALTER INDEX IF EXISTS <original_secondary_index_name> ON <primary_table_name> DISABLED;
      
      -- Drop the index.
      DROP INDEX IF EXISTS <original_secondary_index_name> ON <primary_table_name>;

      Bkz. İkincil dizin silme.

    2. Birincil tablonun değiştirilebilirliğini MUTABLE_ALL olarak ayarlayın:

      ALTER TABLE IF EXISTS <primary_table_name> SET MUTABILITY='MUTABLE_ALL';
    3. Yeni bir ikincil dizin oluşturun. Bkz. CREATE INDEX.

    Not

    Özel zaman damgasıyla veri yazma hakkında ayrıntılı bilgi için bkz. Çok sürümlü veri yönetimi için zaman damgalarını ayarlamak üzere HINT'leri kullanma.

    Not

    İkincil dizin değiştirilebilirliğinin özel zaman damgalarıyla etkileşimi hakkında ayrıntılı bilgi için bkz. Özel zaman damgasıyla dizin güncelleme.

Toplu işlemler

  • S: Toplu güncellemeler neden desteklenmez veya neden "Update's WHERE clause can only contain PK columns" hatası oluşur?

    C: Varsayılan olarak yalnızca tek satırlık güncellemeler desteklenir. Toplu güncellemelerin nasıl etkinleştirileceği hakkında bilgi için bkz. Toplu işlemler SSS.

  • S: Toplu silmeleri nasıl etkinleştiririm?

    C: Toplu silmelerin nasıl etkinleştirileceği ve yapılandırılacağı hakkında bilgi için bkz. Toplu işlemler SSS.