2014-11-07 24 views
5

Çoğunlukla ikili ek verilerini depolayan bir BLOB sütunu content dahil olmak üzere ileti eklerinde çoğunlukla bulunan bir ~ 90 MB veritabanı kullanıyorum.Neden 'IS NULL' 100x blob sütununda 'length() = 0' daha yavaş?

BLOB'lar üzerinde bir dizin oluşturmak akıllıca olmadığından, autoindex dışında hiçbir dizin içermez.

SELECT message_id FROM attachments WHERE content IS NULL; 

ve benim USECASE aynı satırlar neden

SELECT message_id FROM attachments WHERE length(content) = 0; 

:

boş ekleri almak için aşağıdaki querys karşılaştırıldı.

İlk neden 250 ms alır ve ikincisi sadece 1-2 ms'dir (her ikisi de SSD'de)? Bunun sebebi nedir? Gizli bir uzunluk indeksi mi var? Herhangi bir içgörü takdir edildi.

Ek bilgiler

  1. her iki durumda da EXPLAIN QUERY PLAN olduğunu

    0 | 0 | 0 | TARAMA TABLOSU ekleri

  2. olumsuzluk IS NOT NULL vs aynı performansta length() != 0 sonuçları fark 250ms vs 2ms.

  3. Yalnızca {NULL} sütun içerensütunları 250 ms ve WHERE length(content) = 0 AND content IS NULL; 2 ms alır birleşik querys.
+0

Karşılaştırmalarınızın doğru olduğundan emin misiniz? Veriler önbelleğe alınmış mıydı? Sqlite istemcisinin yeni bir örneğini başlattıktan sonra, önce ikinci sorguyu çalıştırırsanız ne olur? Ya da her sorguyu birkaç kez tekrarlayın, en hızlı koşuyu referans olarak alın. –

+0

Bir veya daha fazla sqlite3 işleminde herhangi bir sırada hızlı ve yavaş sorgu sınırsız kez yeniden üretebilir. "Karşılaştırma doğru" ile ne demek istiyorsun? –

+1

Bunun, sütun uzunluğunun depolandığından, yani uzunluk kontrolünün BLOB'un içeriğinin alınmasını gerektirmediği varsayılır. Yine de her kaydı taramanız gerekir, ancak NULL kontrolü için kayıt başına en az bir ek okuma var. Tabi ki, IS NULL kayıt uzunluğunu kullanmak için optimize edilmiş/olmalıdır. Https://www.sqlite.org/fileformat2'ye bir göz atın.html, özellikle "2.1 Kayıt Formatı" bölümü. –

cevap

4

Bunlar sadece farklı sorgusu: LENGTH giriş sıfır dize ise giriş NULL
(ii) 0 ise (here bakınız)

: (i) NULL döndüren bir skaler fonksiyonudur uzunluk (veya bir dizgiye dönüştürülebilirse, resp.). Bu nedenle, Bu nedenle length(content)=0 durumu boş bir dize olan içerik için doğrudur ve içerik NULL olduğunda yanlıştır (çünkü NULL ile karşılaştırma her zaman yanlıştır).

Buna dayanarak, tablonuzun birkaç NULL alanı içerdiğini ve yalnızca bir değeri gerçekten içeren birkaçını içerdiğini tahmin ediyorum. Bu, IS NOT NULL'un karşılaştırılabilir bir performans gösterdiğini söylediğiniz ikinci ek bilginiz tarafından da desteklenir.

+0

Aynı şeyi işaret etmek istedim IS NULL <> len (content) = 0. Eğer alan '' len (content) = 0 ise ama alan boşsa null (content) = null – CiucaS

+0

İyi nokta, 'length (NULL)! = 0' –

+0

Cevabınıza dayanarak, 'length (content) IS NULL'un' content IS NULL' ile aynı satırlarda sonuçlandığını buldum çünkü 'length (X) = NULL' ise ve sadece X = NULL ise ', ama daha hızlı (benim durumumda 500x ve olmayan durum için 20x). Doğrulamak ve cevaba eklemek için bunu kabul etmeyi çok isterim. –

İlgili konular