AWS Türkçe Blog
Amazon Athena için En İyi 10 Performans Ayarlama İpuçları
Orijinal makale: Link (Mert Hocanin ve Pathik Shah)
Bu blog yazısı, EXPLAIN ANALYZE kullanımı, güncellenmiş sıkıştırma, ORDER BY ve JOIN ipuçları, bölüm indekslemeyi kullanma, güncellenmiş istatistikler (performans iyileştirmeleri ile), ek ipuçları gibi daha fazla ayrıntıyla en son Mayıs 2022’de gözden geçirildi ve güncellendi.
Amazon Athena, standart SQL kullanarak Amazon Simple Storage Service‘te (Amazon S3) depolanan verileri analiz etmeyi kolaylaştıran etkileşimli bir sorgu hizmetidir. Athena sunucusuzdur, bu nedenle yönetilecek bir altyapı yoktur ve yalnızca çalıştırdığınız sorgular için ödeme yaparsınız. Athena’nın kullanımı kolaydır. Amazon S3’deki verilerinizi işaret edin, şemayı tanımlayın ve standart SQL kullanarak sorgulamaya başlayın.
Bu yazıda, sorgu performansını artırabilecek en iyi 10 ipucunu inceliyoruz. Amazon S3’de veri depolama ve sorgulara özel ayarlama ile ilgili konulara odaklanıyoruz.
Bu gönderi, Parquet, ORC, TEXTFILE, AVRO, CSV, TSV ve JSON gibi farklı dosya biçimleri hakkında bilgi sahibi olduğunuzu varsayar.
Depolama
Bu bölümde, Athena’dan en iyi şekilde yararlanabilmeniz için verilerinizi nasıl yapılandıracağınız anlatılmaktadır. Aynı uygulamaları, verileriniz Amazon S3’de depolandığında Spark, Presto ve Hive gibi Amazon EMR veri işleme uygulamalarına uygulayabilirsiniz. Aşağıdaki en iyi uygulamaları tartışıyoruz:
- Verilerinizi bölümlere ayırın
- Verilerinizi klasörleyin
- Sıkıştırmayı kullanın
- Dosya boyutunu optimize edin
- Sütunlu (columnar) veri deposu oluşturmayı optimize edin
1. Verilerinizi bölümlere ayırın
Bölümleme (partitioning), tablonuzu bölümlere ayırır ve ilgili verileri tarih, ülke ve bölge gibi sütun değerlerine göre bir arada tutar. Bölümler sanal sütunlar gibi davranır. Bunları tablo oluştururken tanımlarsınız ve sorgu başına taranan veri miktarını azaltarak performansı artırmaya yardımcı olabilirler. Bölüme dayalı filtreler belirleyerek bir sorgu tarafından taranan veri miktarını kısıtlayabilirsiniz. Daha fazla ayrıntı için bkz. Athena’da verileri bölümleme.
Athena, iki adlandırma kuralından birini izleyen Hive bölümlemesini destekler. İlk yöntem, bir eşit sembolü (=) ve ardından değeri takip eden sütun adını bölümlemektir. Örneğin:
Veri kümeniz bu biçimde bölümlenmişse, tablonuza otomatik olarak bölümler eklemek için MSCK REPAIR tablo komutunu çalıştırabilirsiniz.
Verilerinizin yolu önceki biçimi izlemiyorsa, her bölüm için ALTER TABLE ADD PARTITION komutunu kullanarak bölümleri manuel olarak ekleyebilirsiniz. Örneğin:
Bu metodoloji ile, herhangi bir konumu, onları hangi değerlere göre referans göstermek istediğinizle eşleyebilirsiniz.
Aşağıdaki örnek, verilerin bir S3 klasöründe depolanan uçuş tablosundaki yıl sütununda nasıl bölümlendiğini gösterir:
‘WHERE’ yantümcesindeki sütunu kullanarak bir sorguda taranan bölümleri kısıtlayabilirsiniz.
Birden çok sütunu bölüm anahtarı (partition key) olarak da kullanabilirsiniz. Belirli değerler vb. için verileri tarayabilirsiniz.
Bölünecek sütunlara karar verirken aşağıdakileri göz önünde bulundurun:
- Filtre olarak kullanılan sütunlar, bölümleme için iyi adaylardır.
- Bölmenin bir maliyeti vardır. Tablonuzdaki bölüm sayısı arttıkça, bölüm meta verilerini alma ve işleme ek yükü o kadar yüksek ve dosyalarınız o kadar küçük olur. Çok ince bir şekilde bölümleme, ilk faydayı ortadan kaldırabilir.
- Verileriniz bir bölüm değerine aşırı derecede meyilliyse ve çoğu sorgu bu değeri kullanıyorsa, ek yük ilk avantajı ortadan kaldırabilir.
Örneğin, aşağıdaki tablo, bölümlenmiş ve bölümlenmemiş bir tablo arasındaki sorgu çalışma zamanlarını karşılaştırır. Her iki tablo da sıkıştırılmamış ve metin biçiminde depolanmış 74 GB veri içerir. Bölümlenmiş tablo, l_shipdate
sütunu tarafından bölümlenmiştir ve 2.526 bölüme sahiptir.
Sorgu | Bölümlenmemiş Tablo | Fiyat | Bölümlenmiş Tablo | Fiyat | Tasarruf | ||
. | Çalışma zamanı | Taranan veriler | . | Çalışma zamanı | Taranan veriler | . | , |
SELECT count(*) FROM lineitem WHERE l_shipdate = ‘1996-09-01’ | 4,8 saniye | 74,1 GB | 0,36 USD | 0,7 saniye | 29,96 MB | 0,0001 USD | %99 daha ucuz %85 daha hızlı |
SELECT count(*) FROM lineitem WHERE l_shipdate >= ‘1996-09-01’ AND l_shipdate < ‘1996-10-01’ | 4,4 saniye | 74,1 GB | 0,36 USD | 2,0 saniye | 898,58 MB | 0,004 USD | %98 daha ucuz %54 daha hızlı |
EXPLAIN ANALYZE‘ı bir sorgu üzerinde çalıştırmak, bir tablonun bölümlenmiş olup olmadığını ve bölümlenmiş bir sütunun filtre olarak kullanılıp kullanılmadığını belirlemeye yardımcı olur. Bölümlenmiş bir tabloda çalıştırılan aşağıdaki sorguyu göz önünde bulundurun:
Aşağıdaki çıktıda, TableScan
operatörü için, taranan verilerde azalmaya neden olan bir bölüm anahtarı filtresinin kullanıldığını gösteriyor:
Aşağıdaki tabloda gösterildiği gibi, sorguda bir bölüm filtresi kullanılmazsa, bölümlemenin de bir cezası vardır. Verileri fazla bölmediğinizden emin olun. Aşırı bölümleme, bu yazıda daha sonra gösterildiği gibi, performansı düşüren daha fazla sayıda daha küçük dosyaya yol açar.
Sorgu | Bölümlenmemiş Tablo | Bölümlenmiş Tablo | Tasarruf | ||
. | Çalışma zamanı | Taranan veriler | Çalışma zamanı | Taranan veriler | . |
SELECT count(*) FROM lineitem; | 3,4 saniye | 74,1 GB | 8,9 saniye | 74,1 GB | %62 daha yavaş |
Bir AWS Glue Data Catalog’da depolanan tablonuz on binlerce, yüz binlerce ve milyonlarca bölüm içeriyorsa, tabloda bölüm dizinlerini (partition indexes) etkinleştirebilirsiniz. Bölüm dizinleriyle, tüm bölümlerin meta verilerini almak yerine, yalnızca sorgunun filtresindeki bölüm değeri için meta veriler katalogdan alınır. Sonuç, bu tür yüksek oranda bölümlenmiş tablolar için daha hızlı sorgulardır. Aşağıdaki tablo, bölüm dizinlemesi olmayan ve olan bölümlenmiş bir tablo arasındaki sorgu çalışma zamanlarını karşılaştırır. Tablo yaklaşık 100.000 bölüm ve sıkıştırılmamış metin verisi içerir. Siparişler tablosu o_custkey
sütunu ile bölümlenmiştir.
Sorgu | Bölüm dizinlemesi = devre dışı | Bölüm dizinlemesi = etkin | Hız artışı |
. | Çalışma zamanı | Çalışma zamanı | . |
SELECT count(*) FROM orders where o_custkey BETWEEN 1 AND 100 | 19,5 saniye | 1,2 saniye | 16x |
AWS Glue Data Catalog’un Athena’daki bölüm dizinlemesinin avantajları hakkında daha fazla bilgi edinmek için AWS Glue Data Catalog bölüm dizinlerini kullanarak Amazon Athena sorgu performansını iyileştirme bölümüne bakın.
2. Verilerinizi klasörleyin
Verilerinizi bölümlere ayırmanın başka bir yolu, verileri tek bir bölüm içinde klasörlemektir (bucketing). Klasörleme ile birlikte gruplamak istediğiniz satırları içeren bir veya daha fazla sütun belirleyebilir ve bu satırları birden çok klasöre koyabilirsiniz. Bu, yalnızca klasörlenen sütunlar değeri belirtildiğinde okumanız gereken klasörü sorgulamanıza olanak tanır; bu da okunacak veri satırlarının sayısını önemli ölçüde azaltabilir ve bu da sorguyu çalıştırma maliyetini düşürür.
Klasörleme için kullanılacak bir sütun seçerken, kardinalitesi yüksek (yani çok sayıda benzersiz değeri olan) ve sorgu süresi boyunca okunan verileri filtrelemek için sıklıkla kullanılan bir sütun seçmenizi öneririz. Klasörleme için kullanılacak iyi bir sütun örneği, sistemler için kullanıcı kimliği gibi bir birincil anahtar olabilir.
Athena’da, CREATE TABLE deyiminizin içindeki klasörlenmiş sütunu, CLUSTERED BY (<bucketed column>) INTO <number of buckets> BUCKETS ile belirtebilirsiniz. Klasör sayısı, dosyaların en uygun boyutta olması için olmalıdır. Daha fazla ayrıntı için Dosya boyutunu optimize edin bölümüne bakın.
Athena içinde klasörlenmiş tabloları kullanmak için, Athena Apache Spark klasörleme biçimini desteklemediğinden veri dosyalarını oluşturmak üzere Apache Hive kullanmanız gerekir. Klasörlenmiş tabloların nasıl oluşturulacağı hakkında bilgi için Apache Hive belgelerinde LanguageManual DDL BucketedTables‘a bakın.
Ayrıca Athena’nın, örneğin birden çok INSERT INTO ifadesinin çalıştırıldığı durumlarda olduğu gibi, dosya sayısının klasör sayısıyla eşleşmediği tabloları ve bölümleri desteklemediğini unutmayın.
Aşağıdaki tablo, 32 klasör oluşturmak için c_custkey
sütununun kullanıldığı bir müşteri tablosundaki farkı gösterir. Müşteri tablosu 2,29 GB boyutundadır.
Sorgu | Klasörlenmemiş Tablo | Fiyat | Kümelenmiş Sütun Olarak c_custkey Kullanan Klasörlenmiş Tablo | Fiyat | Tasarruf | ||
. | Çalışma zamanı | Taranan veriler | . | Çalışma zamanı | Taranan veriler | . | . |
SELECT count(*) FROM customer where c_custkey = 12677856; | 1,3 saniye | 2,29 GB | 0,01145 USD | 0,82 saniye | 72,94 MB | 0,0003645 USD | %97 daha ucuz %37 daha hızlı |
EXPLAIN ANALYZE’ı önceki sorguda çalıştırmak, klasörlemenin customer
tablosu için Amazon S3’den daha az veri okumaya nasıl yardımcı olduğunu gösterir. Klasörlenmemiş ve klasörlenmiş tabloların sorgusundaki EXPLAIN ANALYZE çıktısının aşağıdaki parçacıkları, farkı anlamak için giriş satırlarını ve veri boyutunu vurgular.
Klasörlenmemiş tablonun çıktısı aşağıdadır:
Klasörlenmiş tablonun çıktısı aşağıdadır:
3. Sıkıştırmayı kullanın
Dosyalar en uygun boyutta olduğu (sonraki bölüme bakın) veya dosyalar bölünebilir olduğu sürece, verilerinizi sıkıştırmak sorgularınızı önemli ölçüde hızlandırabilir. Daha küçük veri boyutları, Amazon S3’den taranan verileri azaltarak sorgu çalıştırma maliyetlerini düşürür. Ayrıca Amazon S3’den Athena’ya ağ trafiğini azaltır.
Aşağıdaki tablo, her bir depolama dosyası formatı için Athena’daki sıkıştırma formatı desteğini özetlemektedir. TEXTFILE formatı TSV, CSV, JSON ve metin için özel SerDes içerir.
. | AVRO | ORC | Parquet | TEXTFILE |
BZIP2 | Yalnızca okuma desteği. Yazma desteklenmiyor. | Hayır | Hayır | Evet |
DEFLATE | Evet | Hayır | Hayır | Hayır |
GZIP | Hayır | Hayır | Evet | Evet |
LZ4 | Hayır | Evet (ham/çerçevesiz) | Hayır | Hadoop uyumlu okuma desteği. Yazma desteklenmiyor. |
LZO | Hayır | Hayır | Evet | Hadoop uyumlu okuma desteği. Yazma desteklenmiyor. |
SNAPPY | Ham/çerçevesiz okuma desteği. Yazma desteklenmiyor. | Evet (ham/çerçevesiz) | Evet (ham/çerçevesiz) | Evet (Hadoop uyumlu çerçeveleme) |
ZLIB | Hayır | Evet | Hayır | Hayır |
ZSTD | Hayır | Evet | Evet | Evet |
Bölünebilir bir dosya Athena’daki yürütme motoru tarafından paralel olarak okunabilirken, bölünemeyen bir dosya paralel olarak okunamaz. Bu, bölünemez bir dosyaya kıyasla bölünebilir bir dosyayı okumak için daha az zaman harcanması anlamına gelir. AVRO, Parquet ve Orc, kullanılan sıkıştırma codec’inden bağımsız olarak bölünebilir. Metin dosyaları için yalnızca BZIP2 ve LZO codec bileşeniyle sıkıştırılmış dosyalar bölünebilir. Metin dosyalarında başka codec bileşenleri kullanılıyorsa, tek bir büyük sıkıştırılmış dosyaya sahip olmaktan kaçının. Bunun yerine, aşağıdaki bölümde tartışıldığı gibi, en uygun boyutta birden çok sıkıştırılmış dosyaya bölün.
Athena için, verileri varsayılan olarak sıkıştıran ve bölünebilir olan Apache Parquet veya Apache ORC’u kullanmanızı öneririz.
Mevcut veri kümenizi sıkıştırmak için AWS Glue ETL işlerini, Amazon EMR’da Spark veya Hive veya Athena’da CTAS veya INSERT INTO ve UNLOAD deyimlerini kullanabilirsiniz. AWS Glue kullanarak sıkıştırmaya yönelik örnek bir komut dosyası aşağıdadır:
4. Dosya boyutlarını optimize edin
Veri tarama paralelleştirilebildiğinde ve veri blokları sırayla okunabildiğinde sorgular daha verimli çalışır. Dosya formatlarınızın bölünebilir olmasını sağlamak, dosyalarınızın büyüklüğü ne olursa olsun paralelliğe yardımcı olur.
Ancak, dosyalarınız çok küçükse (genellikle 128 MB’den az), yürütme motoru S3 dosyalarını açma, dizinleri listeleme, nesne meta verilerini alma, veri aktarımını ayarlama, dosya başlıklarını okuma, sözlüklerin sıkıştırma okuma vb. ek yüküyle ek zaman harcıyor olabilir. Öte yandan, dosyanız bölünebilir değilse ve dosyalar çok büyükse, sorgu işleme, tek bir okuyucunun tüm dosyayı okumasını tamamlamasını bekler. Bu paralelliği azaltabilir.
Küçük dosya sorununuzu çözmenin bir yolu, Amazon EMR’da S3DistCP yardımcı programını kullanmaktır. Daha küçük dosyaları daha büyük nesnelerle birleştirmek için kullanabilirsiniz. Büyük miktarda veriyi optimize edilmiş bir şekilde HDFS’ten Amazon S3’ye, Amazon S3’den Amazon S3’ye ve Amazon S3’den HDFS’e taşımak için de S3DistCP’yi kullanabilirsiniz.
Daha büyük dosyalara sahip olmanın bazı avantajları arasında daha hızlı listeleme, daha az Amazon S3 isteği ve yönetilecek daha az meta veri bulunur.
Örneğin, aşağıdaki tablo, biri tek bir büyük dosya ve diğeri 100.000 küçük dosya tarafından desteklenen iki tablo arasındaki sorgu çalışma zamanlarını karşılaştırır. Her iki tablo da metin biçiminde depolanan yaklaşık 8 GB veri içerir.
Sorgu | Dosya sayısı | Çalışma zamanı |
SELECT count(*) FROM lineitem | 100,000 dosya | 13 saniye |
SELECT count(*) FROM lineitem | 1 dosya | 1,3 saniye |
Hız artışı | ~%90 |
Aşağıdaki örnek komut dosyasında gösterildiği gibi, verilerinizi bölmek için AWS Glue’yu da kullanabilirsiniz.
5. Sütunlu (columnar) veri deposu oluşturmayı optimize edin
Apache Parquet ve Apache ORC, popüler sütunlu veri depolarıdır. Sütun bazında sıkıştırma, farklı kodlama, veri türüne dayalı sıkıştırma ve predicate pushdown kullanarak verileri verimli bir şekilde depolayan özellikler sağlarlar. Onlar da bölünebilir. Genel olarak, daha iyi sıkıştırma oranları veya veri bloklarını atlama, Amazon S3’den daha az bayt okumak anlamına gelir ve bu da daha iyi sorgu performansı ve daha düşük sorgu çalıştırma maliyetleri sağlar. Parquet ve ORC, optimum performans için ayarlayabileceğiniz birkaç parametreye sahiptir.
Ayarlayabileceğiniz bir parametre blok (block) boyutudur (veya şerit – stripe – boyutu). Parquet’deki blok boyutu (veya ORC’daki şerit boyutu), bayt cinsinden boyut açısından bir bloğa sığabilecek maksimum satır sayısını temsil eder. Blok veya şerit boyutu ne kadar büyük olursa, her blokta o kadar fazla satır saklayabilirsiniz. Varsayılan olarak, Parquet blok boyutu 128 MB ve ORC şerit boyutu 64 MB’dir. Çok sütunlu tablolarınız varsa, her sütun bloğunun verimli sıralı I/O’ya izin veren bir boyutta kalmasını sağlamak için daha büyük bir blok boyutu öneririz.
Ayarlanabilecek başka bir parametre de veri bloklarındaki sıkıştırma algoritmasıdır. Parquet GZIP, Snappy (varsayılan), ZSTD ve LZO tabanlı sıkıştırma tekniklerini destekler. ORC ise ZLIB (varsayılan), LZ4, ZSTD ve Snappy sıkıştırma tekniklerini destekler. 10 GB’den fazla veriye sahipseniz, varsayılan sıkıştırma algoritmasıyla başlamanızı ve diğer sıkıştırma algoritmalarıyla test etmenizi öneririz.
Parquet ve ORC dosya biçimlerinin her ikisi de predicate pushdown destekler (predicate filtering olarak da adlandırılır). Her iki formatta da sütun değerlerini temsil eden veri blokları bulunur. Her blok, blok için maks/min değerleri gibi istatistikleri tutar. Bir sorgu çalıştırılırken, bu istatistikler, sorguda kullanılan filtre değerine bağlı olarak bloğun okunması mı yoksa atlanması mı gerektiğini belirler. Bu, taranan verilerin azaltılmasına yardımcı olur ve sorgu çalışma zamanını iyileştirir. Bu özelliği kullanmak için sorguya daha fazla filtre ekleyin (örneğin, bir WHERE yan tümcesi kullanarak).
Atlanacak blok sayısını optimize etmenin bir yolu, ORC veya Parquet dosyalarınızı yazmadan önce yaygın olarak filtrelenen bir sütunu belirlemek ve sıralamaktır. Bu, blok içindeki minimum ve maksimum değerler arasındaki aralığın her bir blok içinde mümkün olduğunca küçük olmasını sağlar. Bu, budanma için daha iyi bir şans verir ve ayrıca taranan verileri daha da azaltır.
Aşağıdaki tablo, metin GZIP, sıralama olmadan Parquet GZIP ve l_partkey
üzerinde sıralama ile Parquet GZIP’de aynı veri kümesi için taranan çalışma zamanlarını ve verileri karşılaştırır.
Sorgu | select l_orderkey from lineitem where l_partkey = 17766770 | Metin Formatına Göre Tasarruf | |
Text GZIP data | Çalışma zamanı | 33,06 saniye | . |
Taranan veriler | 22 GB | . | |
Fiyat | 0,1 USD | . | |
Sıralama olmadan Parquet GZIP | Çalışma zamanı | 1,72 saniye | ~%94 daha hızlı |
Taranan veriler | 2 GB | . | |
Fiyat | 0,009 USD | ~%91 daha ucuz | |
l_partkey üzerinde sıralama ile Parquet GZIP |
Çalışma zamanı | 1,0 saniye | ~%96 daha hızlı |
Taranan veriler | 34,34 MB | . | |
Fiyat | 0,0001 USD | ~%99,9 daha ucuz |
You can convert your existing data to Parquet or ORC using Spark or Hive on Amazon EMR, AWS Glue ETL jobs, or CTAS or INSERT INTO and UNLOAD in Athena. See also the following resources:
Amazon EMR’da Spark veya Hive, AWS Glue ETL işleri veya Athena’da CTAS veya INSERT INTO ve UNLOAD kullanarak mevcut verilerinizi Parquet veya ORC’a dönüştürebilirsiniz. Ayrıca aşağıdaki kaynaklara bakın:
- Athena’da CTAS ve INSERT INTO deyimlerini kullanarak verileri S3 data lake’e çıkarın, dönüştürün ve yükleyin
- Amazon Athena UNLOAD özelliğini kullanarak ETL ve ML işlem hatlarınızı basitleştirin
- AWS Glue ve Amazon S3 ile Data Lake Temeli Oluşturun
- Büyük bir veri kümesini Parquet’e dönüştürme
- Sütunlu biçimlere dönüştürme
Sorgu ayarlama
Athena motoru Presto üzerine inşa edilmiştir. Nasıl çalıştığını anlamak, sorguları çalıştırırken nasıl optimize edebileceğiniz konusunda fikir verir. Bu bölüm aşağıdaki en iyi uygulamaları detaylandırmaktadır:
- ORDER BY deyimini optimize edin
- Birleşimleri (joins) optimize edin
- GROUP BY deyimini optimize edin
- Yaklaşık işlevleri kullanın
- Yalnızca ihtiyacınız olan sütunları ekleyin
6. ORDER BY deyimini optimize edin
ORDER BY deyimi, bir sorgunun sonuçlarını sıralama düzeninde döndürür. Athena, sıralama işlemini birden çok düğümde paralel olarak çalıştırmak için dağıtılmış sıralama kullanır. Üst veya alt N değerlerine bakmak için ORDER BY deyimini kullanıyorsanız, sıralamanın maliyetini azaltmak için bir LIMIT deyimi kullanın, bu da daha hızlı bir sorgu çalışma zamanı sağlar.
Örneğin, aşağıdaki tablo, metin biçiminde sıkıştırılmamış, yaklaşık 60 milyon satırlık 7,25 GB’lık bir tabloya sahip bir veri kümesinin çalışma zamanını özetlemektedir.
Sorgu | Çalışma zamanı |
SELECT * FROM lineitem ORDER BY l_shipdate | 274 saniye |
SELECT * FROM lineitem ORDER BY l_shipdate LIMIT 10000 | 4,6 saniye |
Hız artışı | %98 daha hızlı |
7. Birleşimleri (joins) optimize edin
Doğru bir birleşim sırası seçmek, daha iyi sorgu performansı için çok önemlidir. İki tabloyu birleştirdiğinizde, büyük tabloyu birleşimin sol tarafında ve daha küçük tabloyu birleşimin sağ tarafında belirtin. Athena, sağdaki tabloyu çalışan düğümlere dağıtır ve ardından birleştirmeyi yapmak için soldaki tabloyu akışa alır. Sağdaki tablo daha küçükse, daha az bellek kullanılır ve sorgu daha hızlı çalışır.
Aşağıdaki tablo, metin biçiminde sıkıştırılmamış, yaklaşık 602 milyon satırlık toplam 74 GB veri içeren bir veri kümesindeki çalışma zamanlarını gösterir.
Sorgu | Çalışma zamanı |
SELECT count(*) FROM lineitem, part WHERE lineitem.l_partkey = part.p_partkey | 6,4 saniye |
SELECT count(*) FROM part, lineitem WHERE part.p_partkey = lineitem.l_partkey | 8,1 saniye |
Tasarruf / Hız artışı | ~%20 hız artışı |
Üç ve daha fazla tabloyu birleştirdiğinizde, ara sonucu azaltmak ve diğer tablolarla birleştirmek için önce büyük tabloyu en küçük tabloyla birleştirmeyi düşünebilirsiniz.
Athena ayrıca, aşağıdaki örnekte gösterildiği gibi, sorgu çalışma zamanını iyileştiren ve birleşimli sorgular için taranan verileri ve birleştirmenin sağ tarafındaki tablo için çok seçici bir filtre yan tümcesini azaltan dinamik filtrelemeyi ve dinamik bölüm budamasını destekler. Aşağıdaki sorguda Table_B
, çok seçici bir filtreye sahip küçük bir tablodur (column_A = “value”
). Seçici filtre Table_B
‘ye uygulandıktan sonra, önce birleştirilmiş Table_B.date
sütunu için bir değer listesi çıkarılır ve filtre olarak birleştirilmiş Table_A
tablosuna itilir. Table_A
‘nın gereksiz satırlarını ve bölümlerini filtrelemek için kullanılır. Bu, Table_A
için kaynaktan daha az satır ve bölümün okunmasıyla sonuçlanır ve sorgu çalışma süresinin ve veri tarama boyutunun azaltılmasına yardımcı olur, bu da sorguyu Athena’da çalıştırma maliyetlerinin azaltılmasına yardımcı olur.
8. GROUP BY deyimini optimize edin
GROUP BY operatörü, GROUP BY sütunlarına dayalı olarak satırları, GROUP BY değerlerini bellekte tutan çalışan düğümlere dağıtır. Satırlar alınırken, GROUP BY sütunları bellekte aranır ve değerler karşılaştırılır. GROUP BY sütunları eşleşirse değerler birlikte toplanır.
Sorgunuzda GROUP BY kullanırken, sütunları en yüksek kardinaliteye (yani, eşit olarak dağıtılmış en benzersiz değerlere) göre en düşüğe doğru sıralayın.
Diğer bir iyileştirme, satırlar bellekte tutulduğundan ve GROUP BY deyimi için toplandığından, depolamak için gereken bellek miktarını azaltmak için SELECT ve GROUP BY deyimindeki sütun sayısını sınırlamaktır. Aşağıdaki örnek, SELECT deyimindeki sütunların azaltılmasıyla ilgili sorgulardaki hızlanmayı gösterir.
Sorgu | Çalışma zamanı |
select “l_shipdate”,”l_receiptdate”,”l_commitdate”, “l_linestatus”, count(*) from “lineitem” group by 1,2,3,4 | 33,6 saniye |
select “l_shipdate”, “l_linestatus”, count(*) from “lineitem” group by 1,2 | 6,2 saniye |
Hız artışı | ~%81 hız artışı |
9. Yaklaşık işlevleri kullanın
Büyük veri kümelerini araştırmak için yaygın bir kullanım durumu, COUNT(DISTINCT sütunu) kullanarak belirli bir sütun için farklı değerlerin sayısını bulmaktır. Bir örnek, bir web sayfasına giren benzersiz kullanıcıların sayısına bakmaktır.
Kesin bir sayı gerekli olmadığında (örneğin, hangi web sayfalarını derinlemesine inceleyeceğinizi arıyorsanız), approx_distinct()
kullanmayı düşünün. Bu işlev, tüm dizeler yerine benzersiz değer karmalarını sayarak bellek kullanımını en aza indirmeye çalışır. Dezavantajı ise %2,3’lük bir standart hata olmasıdır.
Aşağıdaki tablo, metin biçiminde sıkıştırılmamış, yaklaşık 600 milyon satırlık 74 GB’lık bir tabloya sahip bir veri kümesindeki hızlanmayı özetlemektedir.
Sorgu | Çalışma zamanı |
SELECT count(distinct l_comment) FROM lineitem; | 7,7 saniye |
SELECT approx_distinct(l_comment) FROM lineitem; | 4,6 saniye |
Hız artışı | ~%40 daha hızlı |
Daha fazla bilgi için Presto belgelerindeki Toplama İşlevleri‘ne bakın.
10. Yalnızca ihtiyacınız olan sütunları ekleyin
Sorgularınızı çalıştırırken, son SELECT ifadesini tüm sütunları seçmek yerine yalnızca ihtiyacınız olan sütunlarla sınırlayın. Sütun sayısını kırpmak, tüm sorgu çalıştırma işlem hattı boyunca işlenmesi gereken veri miktarını azaltır. Bu, özellikle dize tabanlı çok sayıda sütun içeren tabloları sorgularken ve birden çok birleştirme veya toplama gerçekleştirdiğinizde yardımcı olur. Sütunlu biçimler için, yalnızca belirli sütunların verileri okunduğundan Amazon S3’den taranan verileri azaltır.
Aşağıdaki tablo, metin biçiminde sıkıştırılmamış, yaklaşık 60 milyon satırlık 7,25 GB’lık bir tabloya sahip bir veri kümesindeki hızlanmayı özetlemektedir.
Sorgu | Çalışma zamanı |
SELECT * FROM lineitem, orders, customer WHERE lineitem.l_orderkey = orders.o_orderkey AND customer.c_custkey = orders.o_custkey; | 19,7 saniye |
SELECT customer.c_name, lineitem.l_quantity, orders.o_totalprice FROM lineitem, orders, customer WHERE lineitem.l_orderkey = orders.o_orderkey AND customer.c_custkey = orders.o_custkey; | 5,2 saniye |
Tasarruf / Hız artışı | %73 daha hızlı |
Bonus İpuçları
Bu bölümde, ek performans ayarlama ipuçları sağlıyoruz.
Bölme projeksiyonunu kullanarak Bölme İşlemeyi Optimize Etme
Çok sayıda bölümünüz olduğunda ve AWS Glue bölüm indekslemeyi kullanmadığınızda, bölüm bilgilerinin işlenmesi Athena sorguları için bir darboğaz olabilir. Athena’da yüksek oranda bölümlenmiş tabloların sorgu işlemesini hızlandırmak ve bölüm yönetimini otomatikleştirmek için bölüm projeksiyonunu kullanabilirsiniz. Bölüm projeksiyonu, bir metastore’dan almak yerine bölüm bilgilerini hesaplayarak bölümleri sorgulamanıza izin vererek bu ek yükü en aza indirmeye yardımcı olur. AWS Glue tablosuna bölümlerin meta verilerini ekleme ihtiyacını ortadan kaldırır.
Bölüm projeksiyonunda, bölüm değerleri ve konumları, AWS Glue Data Catalog gibi bir havuzdan okumak yerine yapılandırmadan hesaplanır. Bellek içi işlemler genellikle uzak işlemlerden daha hızlı olduğundan, bölüm projeksiyonu, yüksek oranda bölümlenmiş tablolara karşı sorguların çalışma süresini azaltabilir. Sorgunun ve temel alınan verilerin belirli özelliklerine bağlı olarak, bölüm projeksiyonu, bölüm meta veri alımıyla sınırlı sorgular için sorgu çalışma süresini önemli ölçüde azaltabilir.
Bölümlerin şemaları aynı olduğunda veya tabloların şeması bölüm şemalarını her zaman doğru bir şekilde açıklıyorsa, bölüm projeksiyonunu kullanmak idealdir. Kimlikler gibi çok yüksek önem derecesine sahip sütunları veya çok ince ayrıntı düzeyinde tarih aralıklarını bölmek için kullanılabilir.
Daha fazla ayrıntı için Amazon Athena ile bölüm projeksiyonuna bakın.
UNLOAD kullanarak büyük sonuç kümeleri üreten sorguları hızlandırın
Athena’da bir SELECT sorgusu çalıştırmak, Amazon S3’de sıkıştırılmamış CSV biçiminde tek bir sonuç dosyası üretir. Sorgunuzun büyük bir sonuç kümesi (aşağıdaki örnekteki 13 GB gibi) vermesi bekleniyorsa, sonuçları tek bir dosya olarak Amazon S3’ye yazmak için önemli ölçüde zaman harcanır. UNLOAD ile, Amazon S3’de sonuçları birden çok dosyaya bölerek yazma aşamasında harcanan süreyi kısaltabilirsiniz. Ayrıca sonuç kümesi için sonuç biçimini (ORC, Parquet, AVRO, JSON veya TEXTFILE) ve sıkıştırma türünü (varsayılan olarak Parquet, JSON ve TEXTFILE için GZIP ve ORC için ZLIB’dir) belirtebilirsiniz.
Aşağıdaki tablo, SELECT ve UNLOAD deyimleri arasındaki bir karşılaştırmayı göstermektedir. Sorgunun yaklaşık 13 GB sıkıştırılmamış veri vermesi bekleniyor.
Sorgu | SELECT * FROM lineitem LIMIT 85700000 | UNLOAD (SELECT * FROM lineitem LIMIT 85700000) to <s3-output-location> with (format=’TEXTFILE’) | Tasarruf |
Çalışma zamanı | 362 saniye | 33,2 saniye | ~%90 daha hızlı |
Sonuç kümesi | 13 GB (CSV, sıkıştırılmamış) | 3,2 GB (CSV, gzip sıkıştırılmış) | ~%75 azaltılmış depolama |
Sonuç
Bu gönderi, Presto motoruyla Athena’daki etkileşimli analizinizi optimize etmek için en iyi 10 ipucumuzu ele aldı. Aynı uygulamaları Amazon EMR’da Presto’yu kullanırken de uygulayabilirsiniz.