SELECT TRANSFORM deyimi, belirtilen bir alt işlemi başlatmanıza ve standart giriş üzerinden verileri gerekli biçimde iletmenize olanak tanır. Ardından, alt işlemin standart çıkışını ayrıştırarak çıktı verilerini elde edebilirsiniz. SELECT TRANSFORM deyimi, kullanıcı tanımlı tablo değerli işlevler (UDTF) yazmanıza gerek kalmadan diğer programlama dillerindeki betikleri çalıştırmanızı sağlar.
Açıklama
SELECT TRANSFORM ve UDTF'lerin performansı senaryolara göre değişir. Karşılaştırmalı test sonuçları, küçük miktarda veri sorgularken SELECT TRANSFORM ifadesinin UDTF'lerden daha iyi performans gösterdiğini ortaya koymaktadır. Ancak, büyük miktarda veri sorgulandığında UDTF'ler SELECT TRANSFORM'e kıyasla daha üstün performans sunar. SELECT TRANSFORM geliştirmesi kolaydır ve ad hoc sorgular için daha uygundur.
SELECT TRANSFORM çeşitli programlama dilleriyle uyumludur. Bu deyim, komutlar içinde basit özellikleri uygulamak üzere betikler yazmanıza olanak tanır. AWK, Python, Perl ve Shell gibi programlama dilleri bu işlemi destekler. Bu sayede, betik dosyaları yazmak ve kaynak yüklemek gibi ek işlemler yapmanıza gerek kalmaz. Bu durum geliştirme sürecini basitleştirir. Karmaşık özellikleri uygulamak için betik dosyalarını yükleyebilirsiniz. Daha fazla bilgi için bkz. Python betiklerinin çağrılmasına ilişkin örnek ve Java betiklerinin çağrılmasına ilişkin örnek.
Aşağıdaki tabloda, UDTF'ler ile SELECT TRANSFORM arasındaki karşılaştırma sonuçları farklı boyutlarda sunulmaktadır.
|
|
|
|
|
|
|
|
|
|
Veri iletimi işletim sisteminin işlem hattına dayanır. Ancak, işlem hattının önbellek boyutu yalnızca 4 KB'tır ve değiştirilemez. İşlem hattı boş veya tamamen doluysa SELECT TRANSFORM, veri iletimi sırasında verileri okumak ve yazmak için temel sistemleri çağırır. Bu deyim, Java programlarına kıyasla veri iletiminde daha yüksek performans sağlar. |
|
|
|
|
|
|
|
|
|
|
|
|
|
Sınırlamalar
PHP ve Ruby, MaxCompute hesaplama kümelerine dağıtılmamıştır. Bu nedenle, MaxCompute içinde PHP veya Ruby betiklerini çağıramazsınız.
Söz dizimi
select transform(<arg1>, <arg2> ...)
[(row format delimited (fields terminated by <field_delimiter> (escaped by <character_escape>)) (null defined as <null_value>))]
using '<unix_command_line>'
(resources '<res_name>' (',' '<res_name>')*)
[(as <col1>, <col2> ...)]
(row format delimited (fields terminated by <field_delimiter> (escaped by <character_escape>)) (null defined as <null_value>))
SELECT TRANSFORM anahtar sözcüğü: gereklidir. Bu anahtar sözcüğü yerine aynı anlamları taşıyan
mapveyareduceanahtar sözcüklerini kullanabilirsiniz. Söz dizimini daha açık hale getirmek için SELECT TRANSFORM kullanmanızı öneririz.arg1,arg2...: gereklidir. Bu parametreler giriş verilerini belirtir. Bu parametrelerin biçimleri
SELECTdeyimlerindekiyle aynıdır. Varsayılan biçimleri kullanırsanız her parametre için ifade sonuçları örtülü olarak STRING türüne dönüştürülür. Ardından parametreler\tile birleştirilerek belirtilen alt işleme iletilir.-
ROW FORMAT yan tümcesi: isteğe bağlıdır. Bu yan tümce, giriş ve çıkış verilerinin biçimini özelleştirmenize olanak tanır.
Söz diziminde iki ROW FORMAT yan tümcesi kullanılır. İlk yan tümce giriş verilerinin biçimini, ikinci yan tümce ise çıkış verilerinin biçimini belirtir. Varsayılan olarak sütun sınırlayıcısı olarak
\t, satır sınırlayıcısı olarak\nve null değerleri temsil etmek için\Nkullanılır.Notfield_delimiter veya character_escape olarak yalnızca tek bir karakter kullanılabilir. Bu parametreler için bir dize belirtirseniz dizedeki ilk karakter kullanılır.
MaxCompute;
inputRecordReader,outputRecordReaderveSerDegibi Apache Hive tarafından belirtilen biçimlerdeki söz dizimlerini destekler. Bu söz dizimlerini kullanmak için Hive uyumlu veri türü sürümünü etkinleştirmeniz gerekir. Hive uyumlu veri türü sürümünü etkinleştirmek için SQL deyimlerinden önceset odps.sql.hive.compatible=true;ekleyin. Apache Hive tarafından desteklenen söz dizimleri hakkında daha fazla bilgi için bkz. Hive belgeleri.inputRecordReaderveyaoutputRecordReadergibi Apache Hive tarafından desteklenen bir söz dizimi belirtirseniz SQL deyimleri daha yavaş çalıştırılabilir.
-
USING yan tümcesi: gereklidir. Bu yan tümce, bir alt işlemi başlatmak için kullanılan komutu belirtir.
Çoğu MaxCompute SQL deyiminde USING yan tümcesi kaynakları belirtir. Ancak, SELECT TRANSFORM deyimindeki USING yan tümcesi bir alt işlemi başlatmak için komutu belirtir. USING yan tümcesi, Apache Hive söz dizimiyle uyumluluğu sağlamak için kullanılır.
USING yan tümcesinin söz dizimi bir kabuk betiğinin söz dizimine benzer. Ancak, USING yan tümcesi bir kabuk betiği çalıştırmak yerine belirttiğiniz komuta dayalı olarak bir alt işlem oluşturur. Bu nedenle, giriş ve çıkış yönlendirme, işlem hattı ve döngü gibi bazı kabuk özellikleri kullanılamaz. Gerekirse bir alt işlemi başlatmak için komut olarak bir kabuk betiği kullanılabilir.
-
RESOURCES yan tümcesi: isteğe bağlıdır. Bu yan tümce, bir alt işlemin erişebileceği kaynakları belirtir. Bir alt işlemin erişebileceği kaynakları belirtmek için aşağıdaki yöntemlerden birini kullanabilirsiniz:
Kaynakları belirtmek için RESOURCES yan tümcesini kullanın. Örneğin:
using 'sh foo.sh bar.txt' resources 'foo.sh','bar.txt'.-
Kaynakları belirtmek için set odps.sql.session.resources kullanın. Örneğin, kaynakları belirtmek için SQL deyimlerinden önce
set odps.sql.session.resources=foo.sh,bar.txt;bayrağını ekleyebilirsiniz.Bu genel yapılandırma uygulandıktan sonra tüm SELECT TRANSFORM deyimleri kaynaklara erişebilir. Birden çok kaynak dosyasını virgülle (,) ayırın.
-
AS yan tümcesi: isteğe bağlıdır. Bu yan tümce, çıkış sütunlarını ve veri türlerini belirtir. Örneğin:
as(col1 bigint, col2 boolean).Çıkış sütunları için veri türleri belirtmezseniz varsayılan veri türü STRING kullanılır. Örneğin,
AS(col1, col2)ifadesi çıkış sütunlarının STRING türünde olduğunu gösterir.Çıkış verileri, alt işlemin standart çıkışı ayrıştırılarak elde edilir. Belirtilen veri STRING türünde değilse MaxCompute, veri türünü STRING'e dönüştürmek için
CASTişlevini örtülü olarak çağırır. Dönüştürme sırasında çalışma zamanı istisnası oluşabilir.Belirtilen sütunların yalnızca bazılarında veri türlerini belirtemezsiniz. Örneğin:
as(col1, col2:bigint).ASyan tümcesini atlarsanız standart çıkış verilerindeki ilk\töncesindeki alan anahtar, sonraki tüm bölümler değer olur. Bu durumAS(key, value)ifadesine eşdeğerdir.
Kabuk komutlarının çağrılmasına ilişkin örnek
1'den 50'ye kadar başlayan 50 satır veri oluşturmak için bir kabuk komutu çalıştırın. Çıktı data alanıdır. Kabuk komutunun çıktısını SELECT TRANSFORM girdisi olarak kullanın. Örnek deyim:
select transform(script) using 'sh' as (data)
from (
select 'for i in `seq 1 50`; do echo $i; done' as script
) t
;
-- The preceding statement is equivalent to the following statement:
select transform('for i in `seq 1 50`; do echo $i; done') using 'sh' as (data);
Aşağıdaki sonuç döndürülür:
+------------+
| data |
+------------+
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
| 6 |
| 7 |
| 8 |
| 9 |
| 10 |
| 11 |
| 12 |
| 13 |
| 14 |
| 15 |
| 16 |
| 17 |
| 18 |
| 19 |
| 20 |
| 21 |
| 22 |
| 23 |
| 24 |
| 25 |
| 26 |
| 27 |
| 28 |
| 29 |
| 30 |
| 31 |
| 32 |
| 33 |
| 34 |
| 35 |
| 36 |
| 37 |
| 38 |
| 39 |
| 40 |
| 41 |
| 42 |
| 43 |
| 44 |
| 45 |
| 46 |
| 47 |
| 48 |
| 49 |
| 50 |
+------------+
Python komutlarının çağrılmasına ilişkin örnek
1'den 50'ye kadar başlayan 50 satır veri oluşturmak için bir Python komutu kullanın. Çıktı data alanıdır. Python komutunun çıktısını SELECT TRANSFORM girdisi olarak kullanın. Örnek deyim:
select transform(script) using 'python' as (data)
from (
select 'for i in xrange(1, 51): print(i);' as script
) t
;
-- The preceding statement is equivalent to the following statement:
select transform('for i in xrange(1, 51): print(i);') using 'python' as (data);
Aşağıdaki sonuç döndürülür:
+------------+
| data |
+------------+
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
| 6 |
| 7 |
| 8 |
| 9 |
| 10 |
| 11 |
| 12 |
| 13 |
| 14 |
| 15 |
| 16 |
| 17 |
| 18 |
| 19 |
| 20 |
| 21 |
| 22 |
| 23 |
| 24 |
| 25 |
| 26 |
| 27 |
| 28 |
| 29 |
| 30 |
| 31 |
| 32 |
| 33 |
| 34 |
| 35 |
| 36 |
| 37 |
| 38 |
| 39 |
| 40 |
| 41 |
| 42 |
| 43 |
| 44 |
| 45 |
| 46 |
| 47 |
| 48 |
| 49 |
| 50 |
+------------+
AWK komutlarının çağrılmasına ilişkin örnek
Bir test tablosu oluşturun. Test tablosunun ikinci sütununu çıktı olarak sağlamak için bir AWK komutu çalıştırın. Çıktı verisi data alanıdır. AWK komutunun çıktısını SELECT TRANSFORM girdisi olarak kullanın. Örnek deyim:
-- Create a test table.
create table testdata(c1 bigint,c2 bigint);
-- Insert test data into the test table.
insert into table testdata values (1,4),(2,5),(3,6);
-- Execute the SELECT TRANSFORM statement.
select transform(*) using "awk '//{print $2}'" as (data) from testdata;
Aşağıdaki sonuç döndürülür:
+------------+
| data |
+------------+
| 4 |
| 5 |
| 6 |
+------------+
Perl komutlarının çağrılmasına ilişkin örnek
Bir test tablosu oluşturun. Test tablosunun verilerini çıktı olarak sağlamak için bir Perl komutu çalıştırın. Çıktı verisi data alanıdır. Perl komutunun çıktısını SELECT TRANSFORM girdisi olarak kullanın. Örnek deyim:
-- Create a test table.
create table testdata(c1 bigint,c2 bigint);
-- Insert test data into the test table.
insert into table testdata values (1,4),(2,5),(3,6);
-- Execute the SELECT TRANSFORM statement.
select transform(testdata.c1, testdata.c2) using "perl -e 'while($input = <STDIN>){print $input;}'" from testdata;
Aşağıdaki sonuç döndürülür:
+------------+------------+
| key | value |
+------------+------------+
| 1 | 4 |
| 2 | 5 |
| 3 | 6 |
+------------+------------+
Python betiklerinin çağrılmasına ilişkin örnek
-
myplus.py dosyasını oluşturun. Örnek deyimler:
#!/usr/bin/env python import sys line = sys.stdin.readline() while line: token = line.split('\t') if (token[0] == '\\N') or (token[1] == '\\N'): print('\\N') else: print(str(token[0]) +'\t' + str(token[1])) line = sys.stdin.readline() -
Python betik dosyasını MaxCompute'e kaynak olarak ekleyin.
add py ./myplus.py -f;NotPython dosyasını kaynak olarak eklemek için DataWorks konsolunu da kullanabilirsiniz. Daha fazla bilgi için bkz. MaxCompute kaynaklarını oluşturma ve kullanma.
-
Bu dosyayı çağırmak için
SELECT TRANSFORMdeyimini çalıştırın.-- Create a test table. create table testdata(c1 bigint,c2 bigint); -- Insert test data into the test table. insert into table testdata values (1,4),(2,5),(3,6); -- Execute the SELECT TRANSFORM statement. select transform (testdata.c1, testdata.c2) using 'python myplus.py' resources 'myplus.py' as (result1,result2) from testdata; -- The preceding statements are equivalent to the following statements: set odps.sql.session.resources=myplus.py; select transform (testdata.c1, testdata.c2) using 'python myplus.py' as (result1,result2) from testdata;Aşağıdaki sonuç döndürülür:
+------------+------------+ | result1 | result2 | +------------+------------+ | 1 | 4 | | | NULL | | 2 | 5 | | | NULL | | 3 | 6 | | | NULL | +------------+------------+
Java betiklerinin çağrılmasına ilişkin örnek
-
Bir Java betiği yazın ve bunu Sum.jar dosyası olarak dışa aktarın. Örnek Java kodu:
package com.aliyun.odps.test; import java.util.Scanner; public class Sum { public static void main(String[] args) { Scanner sc = new Scanner(System.in); while (sc.hasNext()) { String s = sc.nextLine(); String[] tokens = s.split("\t"); if (tokens.length < 2) { throw new RuntimeException("illegal input"); } if (tokens[0].equals("\\N") || tokens[1].equals("\\N")) { System.out.println("\\N"); } System.out.println(Long.parseLong(tokens[0]) + Long.parseLong(tokens[1])); } } } -
Dosyayı MaxCompute'e kaynak olarak ekleyin.
add jar ./Sum.jar -f; -
Bu dosyayı çağırmak için
SELECT TRANSFORMdeyimini çalıştırın.-- Create a test table. create table testdata(c1 bigint,c2 bigint); -- Insert test data into the test table. insert into table testdata values (1,4),(2,5),(3,6); -- Execute the SELECT TRANSFORM statement. select transform(testdata.c1, testdata.c2) using 'java -cp Sum.jar com.aliyun.odps.test.Sum' resources 'Sum.jar' as cnt from testdata; -- The preceding statements are equivalent to the following statements: set odps.sql.session.resources=Sum.jar; select transform(testdata.c1, testdata.c2) using 'java -cp Sum.jar com.aliyun.odps.test.Sum' as cnt from testdata;Aşağıdaki sonuç döndürülür:
+-----+ | cnt | +-----+ | 5 | | 7 | | 9 | +-----+
Java ve Python hazır bir UDTF çerçevesine sahiptir. Ancak SELECT TRANSFORM betik yazmayı kolaylaştırır. SELECT TRANSFORM ek bağımlılıklar gerektirmez, biçim gereksinimleri yoktur ve hatta çevrimdışı betikleri doğrudan kullanabilir. Çevrimdışı Java betiklerinin kaydedildiği dizin JAVA_HOME ortam değişkeninden, çevrimdışı Python betiklerinin kaydedildiği dizin ise PYTHON_HOME ortam değişkeninden elde edilebilir.
Betiklerin seri olarak çağrılmasına ilişkin örnek
SELECT TRANSFORM deyimlerini seri olarak çalıştırabilirsiniz. Bu işlemi gerçekleştirmek için giriş verilerini ön işlemek amacıyla DISTRIBUTE BY ve SORT BY yan tümcelerini kullanabilirsiniz. Örnek deyim:
select transform(key, value) using '<cmd2>' from
(
select transform(*) using '<cmd1>' from
(
select * from testdata distribute by c2 sort by c1
) t distribute by key sort by value
) t2;
cmd1 ve cmd2, alt işlemleri başlatmak için kullanılan komutlardır.
SELECT TRANSFORM deyimlerini seri olarak çalıştırmak için map ve reduce anahtar sözcüklerini de kullanabilirsiniz.
@a := select * from data distribute by col2 sort by col1;
@b := map * using 'cmd1' distribute by col1 sort by col2 from @a;
reduce * using 'cmd2' from @b;