MaxCompute içindeki Veri Sorgulama Dili (DQL) işlemlerine ilişkin sıkça sorulan sorular; GROUP BY, ORDER BY, JOIN, MAPJOIN, alt sorgular ve küme işlemlerini kapsar.
|
Kategori |
SSS |
|
GROUP BY |
|
|
ORDER BY |
|
|
Alt sorgular |
|
|
Kesişim, birleşim ve fark |
|
|
JOIN |
|
|
MAPJOIN |
|
|
Diğerleri |
Bir MaxCompute SQL deyimi çalıştırırken oluşan "Repeated key in GROUP BY" hatasını nasıl çözerim?
-
Sorun
Bir MaxCompute SQL deyimi çalıştırdığınızda aşağıdaki hata döndürülür:
FAILED: ODPS-0130071:Semantic analysis exception - Repeated key in GROUP BY. -
Neden
SELECT DISTINCTsonrasında sabit değer kullanılmıştır; bu duruma izin verilmez. -
Çözüm
SQL deyimini iki katmana ayırın. İç katman sabit değerler olmadan
DISTINCTmantığını işler, dış katman ise sabit veriyi ekler.
Bir MaxCompute SQL deyimi çalıştırırken oluşan "Expression not in GROUP BY key" hatasını nasıl çözerim?
-
Sorun
Bir MaxCompute SQL deyimi çalıştırdığınızda aşağıdaki hata döndürülür:
FAILED: ODPS-0130071:Semantic analysis exception - Expression not in GROUP BY key : line 1:xx ‘xxx’ -
Neden
GROUP BYyan tümcesine dahil olmayan bir sütun doğrudan başvurulmuştur. Daha fazla bilgi için bkz. GROUP BY yan tümcesi (col_list). -
Çözüm
SELECTlistesindeki sütunların yaGROUP BYyan tümcesindeki sütunlar ya daSUMveyaCOUNTgibi toplama işlevleriyle işlenen sütunlar olduğundan emin olun.
Tablo A üzerinde GROUP BY çalıştırarak Tablo B'yi oluşturdum. Tablo B'deki satır sayısı Tablo A'dan daha az ancak fiziksel depolama boyutu 10 kat daha büyük. Bunun nedeni nedir?
MaxCompute depolama için sütun bazlı sıkıştırma kullanır. Aynı sütundaki ardışık değerler benzerse sıkıştırma oranı yüksek olur. odps.sql.groupby.skewindata=true etkinleştirildiğinde veriler dağıtılır ve bu durum daha düşük bir sıkıştırma oranına neden olur. Sıkıştırmayı iyileştirmek için bir SQL deyimiyle veri yazarken yerel sıralama yapın.
10 milyar kayıt üzerinde bir GROUP BY sorgusu çalıştırmak performansı etkiler mi? GROUP BY için veri hacmi sınırı var mıdır?
Hayır. GROUP BY için veri hacmi sınırı yoktur.
Bir MaxCompute sorgusunun döndürdüğü veriler nasıl sıralanır?
Veriler MaxCompute tablolarından tanımsız bir sırayla okunur. Bir sıralama yan tümcesi olmadığında sorgu sonuçları da sırasızdır.
Verileri sıralamak için SQL deyiminize order by xx limit n yan tümcesini ekleyin.
Tam sıralama için limit değerini n olarak toplam kayıt sayısı + 1 şeklinde ayarlayın.
Büyük bir veri kümesi üzerinde tam sıralama yapmak performansı önemli ölçüde etkiler ve bellek yetersizliği hatalarına neden olabilir. Bu işlemi mümkün olduğunca kaçının.
MaxCompute ORDER BY FIELD NULLS LAST sözdizimini destekler mi?
MaxCompute bu sözdizimini destekler. Daha fazla bilgi için bkz. Diğer SQL sözdizimlerinden farklar.
Bir MaxCompute SQL deyimi çalıştırırken oluşan "ORDER BY must be used with a LIMIT clause" hatasını nasıl çözerim?
-
Sorun
Bir MaxCompute SQL deyimi çalıştırdığınızda aşağıdaki hata döndürülür:
FAILED: ODPS-0130071:[1,27] Semantic analysis exception - ORDER BY must be used with a LIMIT clause, please set odps.sql.validate.orderby.limit=false to use it. -
Neden
ORDER BYtek bir yürütme düğümünde genel sıralama yaptığından, o düğümde aşırı veri işlemeyi önlemek için varsayılan olarak birLIMITyan tümcesi gerekir. -
Çözüm
Senaryonuz
LIMITyan tümcesi olmadanORDER BYkullanımını gerektiriyorsa bu gereksinimi aşağıdaki yöntemlerden biriyle devre dışı bırakın:Proje düzeyinde:
order byilelimityan tümcesinin birlikte kullanılma zorunluluğunu devre dışı bırakmak içinsetproject odps.sql.validate.orderby.limit=false;komutunu çalıştırın.-
Oturum düzeyinde:
order byilelimityan tümcesinin birlikte kullanılma zorunluluğunu devre dışı bırakmak içinset odps.sql.validate.orderby.limit=false;komutunu çalıştırın. Bu komut SQL deyimiyle birlikte gönderilmelidir.Notorder by-limitzorunluluğunun devre dışı bırakılması, büyük bir veri kümesinin tek bir yürütme düğümünde sıralanması anlamına gelir; bu durum performansı düşürür ve kaynak tüketimini artırır.
ORDER BY hakkında daha fazla bilgi için bkz. ORDER BY yan tümcesi (ORDER_condition).
NOT IN alt sorgusu içeren bir MaxCompute SQL deyimi çalıştırdığımda alt sorgu on binlerce kayıt döndürüyor. Ancak IN veya NOT IN sonrasındaki alt sorgu bölümler döndürüyorsa dönen maksimum bölüm sayısı 1.000'dir. NOT IN kullanmam gerekiyorsa bu sorguyu nasıl uygulayabilirim?
Sorguyu left outer join kullanarak yeniden yazın:
select * from a where a.ds not in (select ds from b);
Change the statement to the following:
select a.* from a left outer join (select distinct ds from b) bb on a.ds=bb.ds where bb.ds is null;
İlişkisi olmayan iki tabloyu nasıl birleştiririm?
Dikey birleştirme için union all kullanın. Yatay birleştirme için her iki tabloya da bir ID sütunu eklemek üzere row_number işlevini kullanın, ID üzerinden birleştirin ve ardından gerekli alanları seçin. Daha fazla bilgi için bkz. Birleşim veya ROW_NUMBER.
UNION ALL işlemi sırasında oluşan "ValidateJsonSize error" hatasını nasıl çözerim?
-
Belirtiler
Örneğin
select count(1) as co from client_table union all ...gibi 200 UNION ALL işlemi içeren bir SQL deyimi çalıştırdığınızda aşağıdaki hata oluşur:FAILED: build/release64/task/fuxiWrapper.cpp(344): ExceptionBase: Submit fuxi Job failed, { "ErrCode": "RPC_FAILED_REPLY", "ErrMsg": "exception: ExceptionBase:build/release64/fuxi/fuximaster/fuxi_master.cpp(1018): ExceptionBase: StartAppFail: ExceptionBase:build/release64/fuxi/fuximaster/app_master_mgr.cpp(706): ExceptionBase: ValidateJsonSize error: the size of compressed plan is larger than 1024KB\nStack -
Nedenler
Neden 1: Yürütme planı alt yapının 1024 KB sınırını aşıyor. Yürütme planının uzunluğu SQL deyiminin uzunluğuyla doğru orantılı değildir ve önceden tahmin edilemez.
Neden 2: Bölüm sayısı çok fazladır.
Neden 3: Çok sayıda küçük dosya vardır.
-
Çözümler
Neden 1 çözümü: Uzunluk sınırını aşmamak için uzun SQL deyimini parçalara ayırın.
Neden 2 çözümü: Bölüm sayısını ayarlayın. Daha fazla bilgi için bkz. Bölüm.
Neden 3 çözümü: Küçük dosyaları birleştirin.
Bir JOIN işlemi sırasında oluşan "Both left and right aliases encountered in JOIN" hatasını nasıl çözerim?
-
Sorun
Bir MaxCompute SQL deyimi çalıştırdığınızda aşağıdaki hata döndürülür:
FAILED: ODPS-0130071:Semantic analysis exception - Both left and right aliases encountered in JOIN : line 3:3 ‘xx’: . I f you really want to perform this join, try mapjoin -
Nedenler
Neden 1: ON yan tümcesinde eşitsizlik birleştirme belirtilmiştir, örneğin
table1.c1>table2.c3.Neden 2: JOIN koşulunun bir tarafı her iki tablodan da sütunlara başvurur, örneğin
table1.col1 = concat(table1.col2,table2.col3).
-
Çözümler
-
Neden 1 çözümü: SQL deyimini değiştirin. Birleştirme koşulu eşitlik birleştirme olmalıdır.
NotEşitsizlik birleştirme kullanmanız gerekiyorsa mapjoin ipucu ekleyebilirsiniz. Daha fazla bilgi için bkz. ODPS-0130071.
Neden 2 çözümü: Tablolardan biri küçükse MAPJOIN yöntemini kullanabilirsiniz.
-
Bir JOIN işlemi sırasında oluşan "Maximum 16 join inputs allowed" hatasını nasıl çözerim?
-
Belirtiler
Bir MaxCompute SQL deyimi çalıştırdığınızda aşağıdaki hata döndürülür:
FAILED: ODPS-0123065:Join exception - Maximum 16 join inputs allowed -
Neden
MaxCompute SQL'de bir MAPJOIN işlemi en fazla altı küçük tabloyu, tek bir JOIN işlemi ise en fazla 16 tabloyu destekler.
-
Çözüm
Küçük tabloların bazılarını önce geçici bir tabloda birleştirin. Bu yaklaşım girdi tablosu sayısını azaltır.
Bir JOIN işlemi sırasında sonuçtaki kayıt sayısı orijinal tablodakinden fazla oluyor. Bunu nasıl düzeltebilirim?
-
Belirtiler
Aşağıdaki MaxCompute SQL deyimini çalıştırdıktan sonra sorgu sonucundaki kayıt sayısı table1 içindeki kayıt sayısından büyüktür.
select count(*) from table1 a left outer join table2 b on a.ID = b.ID; -
Neden
Sol dış birleştirme, table2'de eşleşen kayıt bulunmasa bile table1'deki tüm kayıtları döndürür. table2 yinelenen ID'ler içeriyorsa dönen kayıt sayısı artar. Örneğin:
table1aşağıdaki verileri içeriyor olsun.
id
values
1
a
1
b
2
ctable2aşağıdaki verileri içeriyor olsun.
id
values
1
A
1
B
3
Dselect count(*) from table1 a left outer join table2 b on a.ID = b.ID;komutu aşağıdaki sonucu döndürür.
id1
values1
id2
values2
1
b
1
B
1
b
1
A
1
a
1
B
1
a
1
A
2
c
NULL
NULLHer iki tabloda da
id=1olan kayıtlar vardır. Kartezyen çarpım uygulanır ve dört kayıt döndürülür.id=2olan kayıt yalnızcatable1içinde vardır. Bir kayıt döndürülür.id=3olan kayıtlar yalnızcatable2içinde vardır.table1içinde eşleşen kayıt olmadığından hiçbir kayıt döndürülmez.
-
Çözüm
table2içinde yinelenen ID'ler olup olmadığını kontrol edin:select id, count(*) as cnt from table2 group by id having cnt>1 limit 10;Kartezyen çarpımı önlemek için SQL deyimini aşağıdaki gibi yeniden yazın:
select * from table1 a left outer join (select distinct id from table2) b on a.id = b.id;
Neden bir bölüm koşulu belirtilmiş olsa bile JOIN işleminde tam tablo taraması yasaklanır?
-
Sorun
Aynı kod iki projede çalıştırıldığında birinde başarılı olurken diğerinde başarısız olur.
select t.stat_date from fddev.tmp_001 t left outer join (select '20180830' as ds from fddev.dual ) t1 on t.ds = 20180830 group by t.stat_date;Başarısız çalışan yürütme aşağıdaki hatayı bildirir:
Table(fddev,tmp_001) is full scan with all partitions,please specify partitions predicates. -
Neden
Bir
SELECTişlemi gerçekleştirirken bölüm koşuluWHEREyan tümcesinde olmalıdır. Bu amaçlaONyan tümcesinin kullanılması standart dışıdır.Yürütme bir projede
set odps.sql.outerjoin.supports.filters=falsekomutuyla yapılandırıldığı için başarılı oldu. Bu komutONyan tümcesindeki koşulu filtre koşuluna dönüştürür. Bu davranış Hive sözdizimiyle uyumludur ancak SQL standardına uygun değildir. -
Çözüm
Bölüm filtre koşulunu WHERE yan tümcesine yerleştirin.
Bir JOIN işlemi için bölüm budama koşulu ON yan tümcesinde veya WHERE yan tümcesinde olduğunda bölüm budama etkin olur mu?
Bölüm budama koşulu WHERE yan tümcesindeyse bölüm budama etkin olur.
Koşul ON yan tümcesindeyse bölüm budama ayrıntı tablosunda etkin olur ancak birincil tabloda etkin olmaz. Bu durum birincil tablonun tam taramasına neden olur.
Bölüm budama hakkında daha fazla bilgi için bkz. Bölüm budamanın geçerliliğini değerlendirme.
Birden çok küçük tabloyu önbelleğe almak için MAPJOIN'u nasıl kullanırım?
MAPJOIN küçük tabloları bellekte önbelleğe alarak sorguları hızlandırır. MAPJOIN ipucunda tablo takma adlarını belirtin.
Projede iris adlı bir tablo olduğunu varsayalım. Tablo verileri aşağıdaki gibidir.
+——————————————————————————————————————————+
| Field | Type | Label | Comment |
+——————————————————————————————————————————+
| sepal_length | double | | |
| sepal_width | double | | |
| petal_length | double | | |
| petal_width | double | | |
| category | string | | |
+——————————————————————————————————————————+
Aşağıdaki örnek komut küçük tabloları önbelleğe almak için MAPJOIN kullanır.
select
/*+ mapjoin(b,c) */
a.category,
b.cnt as cnt_category,
c.cnt as cnt_all
from iris a
join
(
select count(*) as cnt,category from iris group by category
) b
on a.category = b.category
cross join
(
select count(*) as cnt from iris
) c;
Bir MAPJOIN içindeki büyük ve küçük tabloların yerleri değiştirilebilir mi?
Evet. Sistem büyük ve küçük tabloları depolama boyutuna göre ayırt eder ve JOIN işlemini hızlandırmak için küçük tabloyu belleğe yükler.
Tabloların yerlerinin değiştirilmesi hataya neden olmaz ancak performans düşer.
Bir MaxCompute SQL deyimi için filtre koşulu ayarladıktan sonra giriş verilerinin 100 GB'ı aştığını belirten bir hata alıyorum. Bunu nasıl düzeltebilirim?
Önce verileri bölüm alanına göre filtreleyin, ardından diğer bölüm dışı alanlara göre filtreleyin. Giriş veri hacmi bölüm düzeyindeki filtrelemeden sonra hesaplanır.
MaxCompute SQL'deki bulanık sorgular için kullanılan WHERE yan tümcesi düzenli ifadeleri destekler mi?
Evet. Örneğin, select * from user_info where address rlike '[0-9]{9}'; dokuz basamaklı sayı içeren kayıtları bulur.
Yalnızca 100 kaydı eşitlemek istiyorsam WHERE filtre koşulunda LIMIT'i nasıl kullanabilirim?
Filtre koşulunda LIMIT desteklenmez. Önce 100 kaydı seçmek için bir SQL deyimi kullanın, ardından eşitleme işlemini gerçekleştirin.
Sorgu verimliliğini nasıl artırabilirim? Bölüm ayarlarını değiştirebilir miyim?
Tam tablo taraması yapmadan belirli bölümlerde veri eklemek, güncellemek veya okumak için tabloyu bölüm alanlarına göre bölümlere ayırın. Daha fazla bilgi için bkz. Tablo işlemleri.
MaxCompute SQL WITH AS ifadesini destekler mi?
Evet. MaxCompute okunabilirliği ve yürütme verimliliğini artırmak için standart SQL Ortak Tablo İfadelerini (CTE) destekler. Daha fazla bilgi için bkz. COMMON TABLE EXPRESSION (CTE).
Tek bir satırdaki verileri birden çok satıra nasıl bölerim?
Tek bir satırı birden çok satıra bölmek ve elde edilen verileri toplamak için Split ve Explode gibi tablo üreten işlevlerle birlikte LATERAL VIEW kullanın.
İstemcideki odps_config.ini dosyasında use_instance_tunnel=false ve instance_tunnel_max_record=10 olarak ayarladım. Neden bir SELECT deyimi hâlâ çok sayıda kayıt çıktılıyor?
instance_tunnel_max_record ayarının etkili olması için use_instance_tunnel=false değerini use_instance_tunnel=true olarak değiştirin.
Bir alanın Çince karakter içerip içermediğini belirlemek için düzenli ifadeyi nasıl kullanırım?
Örnek:
select 'field' rlike '[\\x{4e00}-\\x{9fa5}]+';