Veritabanı performansı için uygulama tasarımı

Bir SQLStatement nesnesini çalıştırdıktan sonra onun text özelliğini değiştirmeyin. Bunun yerine, her SQL ifadesi için bir SQLStatement örneği ve farklı değerler sağlamak için ifade parametreleri kullanın.

Bir SQL ifadesi yürütülmeden önce, çalışma zamanı ifadenin yürütülmesi için dahili olarak gerçekleştirilecek adımları belirlemek üzere ifadeyi hazırlar (derler). Daha önce yürütülmemiş olan bir SQLStatement örneğinde SQLStatement.execute() yöntemini çağırdığınızda, ifade yürütülmeden önce otomatik olarak hazırlanır. Daha sonraki execute() yöntemi çağrılarında, SQLStatement.text özelliği değişmediği sürece, ifade hala hazır durumdadır. Sonuç olarak, ifade daha hızlı yürütülür.

İfadelerin yürütülmesi arasındaki değerler değişiyorsa, ifadeleri yeniden kullanmaktan en iyi şekilde fayda sağlamak üzere ifadenizi özelleştirmek için ifade parametrelerini kullanın. (İfade parametreleri, SQLStatement.parameters ilişkilendirici dizi özelliği kullanılarak belirtilir.) SQLStatement örneğinin text özelliğinin aksine, ifade parametrelerinin değerlerini değiştirdiğinizde, çalışma zamanının ifadeyi yeniden hazırlaması gerekmez.

Bir SQLStatement örneğini bir kez hazırlandıktan sonra yeniden kullandığınızda, uygulamanız bu SQLStatement örneğine giden bir başvuruyu saklamalıdır. Örneğe giden bir başvuruyu tutmak için, değişkeni işlem kapsamlı değil, sınıf kapsamlı bir değişken olarak belirtin. SQLStatement öğesini sınıf kapsamlı bir değişken haline getirmenin iyi bir yolu, uygulamanızı SQL ifadesinin tek bir sınıfta sarılacağı biçimde yapılandırmaktır. Bileşim halinde yürütülen bir ifade grubu da tek bir sınıfta sarılabilir. (Bu teknik Komut tasarım yapısını kullanma olarak da bilinir.) Örnekler bu sınıfın üye değişkenleri olarak tanımlandığında, sarma sınıfı örneği uygulamada bulunduğu sürece, bu örnekler de kalıcı olur. Minimum düzeyde, örneğin bellekte kalması için işlevin dışında yer alan bir SQLStatement örneği içeren bir değişken tanımlayabilirsiniz. Örneğin, SQLStatement örneğini ActionScript sınıfında yer alan bir üye değişkeni veya bir JavaScript dosyasında yer alan, işlev olmayan bir değişken olarak belirleyin. Daha sonra, sorguyu gerçekten yürütmek istediğinizde ifadenin parametre değerlerini ayarlayabilir ve execute() yöntemini çağırabilirsiniz.

Veri karşılaştırma ve sıralama için çalıştırma hızını artırmak amacıyla veritabanı dizinlerini kullanın.

Bir sütun için dizin oluşturduğunuzda, veritabanı o sütunun verilerinin bir kopyasını saklar. Kopya sayısal veya alfabetik sırada saklanır. Bu sıralama, veri tabanının değerleri hızla eşleştirmesine (örneğin eşitlik operatörünü kullanırken) ve ortaya çıkan verileri ORDER BY deyimini kullanarak sıralamasına olanak tanır.

Veritabanı dizinleri sürekli olarak güncel tutulur ve bu o tablodaki veri değiştirme işlemlerinin (EKLE veya GÜNCELLE) biraz daha yavaş olmasına neden olur. Ancak, veri alma hızında önemli ölçüde artış olabilir. Bu performans dengelemesinden dolayı, her tablonun her sütununu dizinlemeyin. Bunun yerine, dizinlerinizi tanımlamak için bir strateji kullanın. Dizinleme stratejinizi planlamak için aşağıdaki kılavuzları kullanın:

  • WHERE veya ORDER BY deyimlerinde tabloları birleştirmek için kullanılan dizin sütunları

  • Sütunlar sıkça birlikte kullanılıyorsa, onları tek bir dizinde olacak şekilde birlikte dizinleyin

  • Alfabetik olarak sıralanmış biçimde aldığınız ve metin verileri içeren bir sütunda, dizin için COLLATE NOCASE karşılaştırmasını belirtin

Uygulamanın boşta kaldığı zamanlarda SQL ifadelerini önceden derlemeyi göz önünde bulundurun.

Bir SQL ifadesi ilk defa çalıştığında, SQL metni, veritabanı motoru tarafından hazırlandığı (derlendiği) için daha yavaş olur. Bir ifadenin hazırlanması ve yürütülmesi çaba gerektiren bir işlem olduğundan, bu işleme yönelik bir strateji başlangıç verilerini önceden yüklemek ve daha sonra diğer ifadeleri arka planda yürütmektir:

  1. Önce uygulamanın gerektirdiği verileri yükleyin..

  2. Uygulamanızın ilk başlangıç işlemleri tamamlandığında veya uygulamadaki başka bir “boş” zamanda diğer ifadeleri yürütün.

Örneğin, uygulamanızın birinci ekranını görüntülemek için veritabanına hiç erişmediğini varsayın. Bu durumda, veritabanı bağlantısının açılmasından önce ekranın görüntülenmesini bekleyin. Son olarak, SQLStatement örneklerini oluşturun ve çalıştırabildiklerinizi çalıştırın.

Alternatif olarak, uygulamanızın başlar başlamaz belirli bir sorgunun sonucu gibi bazı verileri görüntülediğini varsayın. Bu durumda, devam edin ve bu sorguya ilişkin SQLStatement örneğini yürütün. Başlangıç verileri yüklendikten ve görüntülendikten sonra, diğer veritabanı işlemleri için SQLStatement örneklerini oluşturun ve mümkünse diğer gerekli ifadeleri daha sonra yürütün.

Pratikte, SQLStatement örneklerini yeniden kullanıyorsanız, ifadenin hazırlanması için gereken ek süre yalnızca tek seferlik bir süreçtir. Büyük olasılıkla, bunun genel performans üzerinde büyük bir etkisi olmaz.

Çoklu SQL veri değişimi işlemlerini bir işlemin içinde gruplayın.

Veri ekleme ve değiştirmeyi içeren çok sayıda SQL ifadesi yürüttüğünüzü varsayın ( INSERT veya UPDATE ifadeleri). Tüm ifadeleri açık bir işlem içinde yürüterek performansta önemli bir artış sağlayabilirsiniz. Açık olarak bir işlem başlatmazsanız, ifadelerden her biri kendisine ait otomatik olarak oluşturulmuş işlemlerde çalışır. Her işlemin (her ifadenin) yürütülmesi tamamlandığında, çalışma zamanı elde edilen verileri diskteki veritabanı dosyasına yazar.

Diğer taraftan, açık olarak bir işlem oluşturur ve ifadeleri bu işlem bağlamında yürütürseniz ne olacağını düşünün. Çalışma zamanı bellekteki tüm değişiklikleri yapar, daha sonra işlem gerçekleştiğinde tüm değişiklikleri bir defada veritabanı dosyasına yazar. Verilerin diske yazılması genellikle işlemin en zaman yoğunluklu bölümüdür. Sonuç olarak, her SQL ifadesi için bir kez diske yazmak yerine bir defada yazmak, performansı önemli ölçüde artırabilir.

Büyük SELECT sorgu sonuçlarını SQLStatement sınıfının execute() ( prefetch parametresi ile) ve next() yöntemlerini kullanarak parçalar halinde işleyin..

Büyük bir sonuç kümesi alan bir SWL ifadesi çalıştırdığınızı varsayın. Ardından, uygulama her veri satırını bir döngü halinde işler. Örneğin, verileri biçimlendirir veya ondan nesneler oluşturur. Verilerin işlenmesi uzun zaman alabilir ve bu kilitlenen veya yanıt vermeyen bir ekran gibi oluşturma sorunlarına neden olabilir. Eş zamanlı olmayan işlemler bölümünde açıklandığı gibi, işi parçalara bölmek de bir çözümdür. SQL veritabanı API’si, veri işleme sürecini bölmeyi kolaylaştırır.

SQLStatement sınıfının execute() yönteminde isteğe bağlı bir prefetch parametresi vardır (ilk parametre). Bir değer sağlarsanız, bu değer veritabanının çalıştırma tamamlandığı zaman döndürdüğü sonuç satırlarının maksimum sayısını belirtir.

dbStatement.addEventListener(SQLEvent.RESULT, resultHandler); 
dbStatement.execute(100); // 100 rows maximum returned in the first set

Sonuç verinin birinci kümesi döndürüldüğünde, ifadeyi çalıştırmaya devam etmek ve başka bir sonuç satırlar kümesi almak için next() yöntemini çağırabilirsiniz. execute() yöntemi gibi, next() yöntemi de döndürülecek maksimum satır sayısı belirten prefetch parametresini kabul eder:

// This method is called when the execute() or next() method completes 
function resultHandler(event:SQLEvent):void 
{ 
    var result:SQLResult = dbStatement.getResult(); 
    if (result != null) 
    { 
        var numRows:int = result.data.length; 
        for (var i:int = 0; i < numRows; i++) 
        { 
            // Process the result data 
        } 
         
        if (!result.complete) 
        { 
            dbStatement.next(100); 
        } 
    } 
}

Verilerin tamamı yüklenene kadar next() yöntemini çağırmaya devam edebilirsiniz. Önceki listede gösterildiği gibi, verilerin tamamının ne zaman yüklendiğini anlayabilirsiniz. execute() veya next() yöntemlerinin her bitişinde oluşturulan SQLResult nesnesinin complete özelliğini kontrol edin.

Not: Sonuç verilerini işleme sürecini bölmek için prefetch parametresini ve next() yöntemini kullanın. Bir sorgunun sonuçlarını, sonuç kümesinin bir bölümüne sınırlandırmak için bu parametreyi kullanmayın. Bir ifadenin sonuç kümesinden yalnızca sütunların bir alt kümesini almak istiyorsanız SELECT deyiminin LIMIT ifadesini kullanın. Sonuç büyükse, yine de sonuçların işlenme sürecini bölmek için prefetch parametresini ve next() yöntemini kullanabilirsiniz.
Çoklu ifadeleri eşzamanlı olarak çalıştırmak için senkronize olmayan çoklu SQLConnection nesnelerini tek bir veri tabanıyla kullanmayı deneyin.

Bir SQLConnection nesnesi openAsync() yöntemini kullanarak bir veritabanına bağlandığında, ana çalışma zamanı çalıştırma parçacığı yerine arka planda çalışır. Ek olarak, her SQLConnection kendi arka plan iş parçacığında çalışır. Çoklu SQLConnection nesnelerini kullanarak çoklu SQL ifadelerini eşzamanlı olarak etkili bir biçimde çalıştırabilirsiniz.

Bu yaklaşımın aynı zamanda olası dezavantajları da vardır. En önemlisi, her ek SQLStatement nesnesi ek bellek gerektirir. Ek olarak, eşzamanlı çalıştırmalar da özellikle tek bir CPU veya CPU çekirdeği olan makinelerde işlemcinin daha çok çalışmasına neden olur. Bu sıkıntılardan dolayı, bu yaklaşım mobil aygıtlarda kullanım için tavsiye edilmez.

Başka bir sıkıntı ise, SQLStatement nesnelerinin yeniden kullanımından sağlanabilecek faydanın bir SQLStatement nesnesinin tek bir SQLConnection nesnesine bağlı olmasından dolayı kaybolabilmesidir. Bu yüzden, SQLStatement nesnesi, ilişkili SQLConnection nesnesinin zaten kullanımda olması durumunda yeniden kullanılamaz.

Tek bir veritabanına bağlı çoklu SQLConnection nesneleri kullanmak istiyorsanız, her birinin ifadelerini kendi işleminde çalıştırdığını aklınızda tutun. Bu ayrı işlemleri, ekleme, değiştirme veya veri silme gibi verileri değiştiren herhangi bir kodda hesaba kattığınızdan emin olun.

Paul Robertson çoklu SQLConnection nesneleri kullanmanın olası dezavantajlarını minimuma indirirken faydalarını birleştirmenize yardımcı olacak açık kaynaklı bir kod kütüphanesi oluşturdu. Kütüphane SQLConnection nesnelerinden oluşan bir havuz kullanır ve ilişkili SQLStatement nesnelerini yönetir. Böylece, SQLStatement nesnelerinin yeniden kullanılmasını ve çoklu ifadeleri eşzamanlı olarak çalıştırmak için çoklu SQLConnection nesnelerinin mevcut olmasını sağlar. Daha fazla bilgi ve kütüphaneyi indirmek için bkz. http://probertson.com/projects/air-sqlite/ .