Tüm Ürünler
Search
Belge Merkezi

MaxCompute:UPDATE | DELETE

Son Güncelleme:Oct 10, 2026

MaxCompute, Transactional tablolar ve Delta Tablolarındaki satır düzeyindeki verileri silmek veya güncellemek için DELETE ve UPDATE işlemlerini kullanmanıza olanak tanır.

Bu konudaki komutları aşağıdaki platformlarda çalıştırabilirsiniz:

Önkoşullar

DELETE veya UPDATE işlemlerini çalıştırmadan önce, hedef Transactional tablo veya Delta Tablosu üzerinde Select ve Update izinlerine sahip olmanız gerekir. Yetkilendirme hakkında daha fazla bilgi için bkz. MaxCompute izinleri.

İşlev tanıtımı

Geleneksel veritabanlarında kullanımlarına benzer şekilde, MaxCompute'deki DELETE ve UPDATE özellikleri bir tablodaki belirli satırları silebilir veya güncelleyebilir.

DELETE veya UPDATE özelliğini kullandığınızda sistem, her silme veya güncelleme işlemi için otomatik olarak bir Delta dosyası oluşturur. Bu dosya kullanıcılar tarafından görülemez ve silinen veya güncellenen verilerle ilgili bilgileri kaydeder. Uygulama şu şekilde çalışır:

  • DELETE: Delta dosyası, Transactional tablonun temel dosyasında hangi kaydın silindiğini ve hangi silme işleminde gerçekleştiğini belirlemek için txnid(BIGINT) ve rowid(BIGINT) alanlarını kullanır. Temel dosya, bir tablonun alttaki depolama biçimidir.

    Örneğin, t1 tablosunun temel dosyasının f1 olduğunu ve içeriğinin a, b, c, a, b olduğunu varsayalım. DELETE FROM t1 WHERE c1='a'; komutunu çalıştırdığınızda sistem ayrı bir f1.delta dosyası oluşturur. txnid değeri t0 ise f1.delta içeriği ((0, t0), (3, t0)) olur. Bu, 0. ve 3. satırların t0 işlemi sırasında silindiğini gösterir. Başka bir DELETE işlemi çalıştırırsanız sistem başka bir Delta dosyası (örneğin f2.delta) oluşturur. Bu dosya da orijinal temel dosya f1'e başvurur. Verileri sorguladığınızda sistem, silinmemiş kayıtları almak için temel dosya f1'i mevcut tüm Delta dosyalarıyla birleştirir.

  • UPDATE: Bir UPDATE işlemi, bir DELETE işlemi ve bir INSERT INTO işlemi olarak uygulanır.

DELETE ve UPDATE özelliklerinin aşağıdaki avantajları vardır:

  • Yazılan veri miktarının azaltılması

    Daha önce MaxCompute, tablo verilerini silmek veya güncellemek için INSERT INTO veya INSERT OVERWRITE işlemlerini kullanıyordu. Daha fazla bilgi için bkz. INSERT INTO | INSERT OVERWRITE. Bir tablo veya bölümdeki küçük miktardaki verileri güncellemek gerektiğinde INSERT işlemi kullanmak, önce tablodan tüm verileri okumanızı, SELECT işlemi kullanarak verileri güncellemenizi ve son olarak INSERT işlemiyle tüm verileri tabloya geri yazmanızı gerektirirdi. Bu yöntem verimsizdi. DELETE veya UPDATE özelliği kullanıldığında sistemin tüm verileri geri yazması gerekmez; bu da yazılan veri miktarını önemli ölçüde azaltır.

    Not
    • Kullandıkça öde faturalama yöntemi için DELETE, UPDATE ve INSERT OVERWRITE işlerinin yazma işlemleri için ücretlendirilmezsiniz. Ancak DELETE ve UPDATE işleri, kayıtları silme olarak işaretlemek veya güncellenmiş kayıtları geri yazmak için bölümlerden veri okumalıdır. Bu okuma işlemleri, SQL işleri için kullandıkça öde faturalama modeline göre hala ücretlendirilir. Bu nedenle, daha az veri yazılmasına rağmen DELETE ve UPDATE işleri INSERT OVERWRITE işlerine kıyasla maliyetleri mutlaka düşürmez.

    • Abonelik faturalama yöntemi için DELETE ve UPDATE daha az yazma kaynağı tüketir. INSERT OVERWRITE ile karşılaştırıldığında aynı kaynaklarla daha fazla iş çalıştırabilirsiniz.

  • Tablonun en son durumunu doğrudan okuma

    Daha önce MaxCompute, toplu veri güncellemeleri için ziper tablolar kullanıyordu. Bu yöntem, bir kaydın yaşam döngüsünü izlemek için tabloya start_date ve end_date gibi yardımcı sütunlar eklemeyi gerektiriyordu. Tablonun en son durumunu sorgulamak için sistemin mevcut durumu bulmak amacıyla zaman damgalarına göre büyük miktarda veriyi filtrelemesi gerekiyordu; bu da karmaşıktı. DELETE ve UPDATE özellikleriyle tablonun en son durumunu doğrudan okuyabilirsiniz. Sistem, verilerin geçerli görünümünü sağlamak için temel dosyaları ve Delta dosyalarını birleştirir.

Önemli

DELETE ve UPDATE işlemlerinin birden çok kez yürütülmesi, bir Transactional tablonun alttaki depolamasını artırır. Bu durum depolama maliyetlerini artırır ve sonraki sorgu performansını düşürür. Altta yatan verileri periyodik olarak birleştirmeniz (compact) gerekir. Birleştirme işlemleri hakkında daha fazla bilgi için bkz. Transactional tablo dosyalarını birleştirme.

Aynı hedef tablo üzerinde birden fazla iş eşzamanlı olarak çalıştırılırsa iş çakışmaları oluşabilir. Daha fazla bilgi için bkz. ACID semantiği.

Kullanım senaryoları

DELETE ve UPDATE özellikleri, bir tablo veya bölümdeki küçük miktardaki verilerin rastgele ve düşük sıklıkta silinmesi veya güncellenmesi için uygundur. Örneğin, bir tablo veya bölümdeki satırların %5'inden azı üzerinde günlük (T+1) bazda periyodik olarak toplu silme veya güncelleme işlemleri gerçekleştirebilirsiniz.

DELETE ve UPDATE özellikleri, yüksek sıklıkta güncelleme, silme veya hedef tabloya gerçek zamanlı yazma işlemleri için uygun değildir.

Sınırlamalar

  • DELETE ve UPDATE özellikleri yalnızca Transactional tablolar ve Delta Tablolarında kullanılabilir ve aşağıdaki sınırlamalara tabidir:

    Not

    Transaction tabloları ve Delta Tabloları hakkında daha fazla bilgi için bkz. Transaction Table ve Delta Table Parametreleri.

  • Delta Tabloları için UPDATE sözdizimi birincil anahtar (PK) sütunlarının değiştirilmesini desteklemez.

Dikkat edilecek noktalar

Bir tablo veya bölümdeki verileri silmek veya güncellemek için DELETE veya UPDATE işlemlerini kullanırken aşağıdaki hususları göz önünde bulundurun:

  • Bir tablodaki küçük miktardaki verileri silmek veya güncellemek ve hem işlem hem de sonraki okumalar nadiren yapılıyorsa DELETE ve UPDATE işlemlerini kullanın. Birden çok silme veya güncelleme işlemi gerçekleştirdikten sonra tablonun depolama ayak izini azaltmak için tablonun temel dosyalarını ve Delta dosyalarını birleştirin. Daha fazla bilgi için bkz. Transactional tablo dosyalarını birleştirme.

  • Çok sayıda satırı (%5'ten fazlasını) nadiren siler veya günceller ancak tablo üzerindeki sonraki okuma işlemleri sık sık yapılıyorsa INSERT OVERWRITE veya INSERT INTO kullanın. Daha fazla bilgi için bkz. INSERT INTO | INSERT OVERWRITE.

    Örneğin, bir iş senaryosu günde 10 kez verilerin %10'unu silmeyi veya güncellemeyi içerebilir. DELETE ve UPDATE işlemlerinin maliyetlerinin ve sonraki okuma performansı düşüşünün INSERT OVERWRITE veya INSERT INTO kullanımına kıyasla daha düşük olup olmadığını değerlendirin. Daha uygun seçeneği belirlemek için iki yöntemin verimliliğini özel senaryonuzda karşılaştırın.

  • Veri silme işlemi Delta dosyaları oluşturur; bu da işlemin depolamayı hemen azaltmadığı anlamına gelir. DELETE işlemi kullanarak depolamayı azaltmak istiyorsanız tablonun temel dosyalarını ve Delta dosyalarını birleştirmeniz gerekir. Daha fazla bilgi için bkz. Transactional tablo dosyalarını birleştirme.

  • MaxCompute, DELETE ve UPDATE işlerini toplu işlemler olarak çalıştırır. Her ifade kaynak tüketir ve ücrete tabidir. Verileri toplu halde silmeli veya güncellemelisiniz. Örneğin, her biri yalnızca bir veya birkaç satır üzerinde işlem yapan birçok satır düzeyinde güncelleme işi oluşturup göndermek için bir Python betiği kullanırsanız her ifade, SQL tarafından taranan giriş veri miktarına göre maliyet oluşturur. Bu tür birçok ifadenin kümülatif maliyeti giderleri önemli ölçüde artırır ve sistem verimliliğini azaltır. Aşağıda komut örnekleri verilmiştir.

    • Önerilen yöntem:

      UPDATE table1 SET col1= (SELECT value1 FROM table2 WHERE table1.id = table2.id AND table1.region = table2.region);
    • Önerilmeyen yöntem:

      UPDATE table1 SET col1=1 WHERE id='2021063001' AND region='beijing';                 
      UPDATE table1 SET col1=2 WHERE id='2021063002' AND region='beijing';

Veri silme

DELETE işlemi, bir Transactional tablo veya Delta Tablosundan belirtilen koşulları karşılayan bir veya daha fazla satırı siler.

  • Sözdizimi

    DELETE FROM <table_name> [[AS] alias] [WHERE <condition>];
  • Parametreler


    Parametre


    Gerekli


    Açıklama


    table_name


    Evet


    DELETE işlemini çalıştırmak istediğiniz Transactional tablo veya Delta Tablosunun adı.


    alias


    Hayır


    Tablo için takma ad.


    where_condition


    Hayır


    Koşulu sağlayan verileri filtrelemek için bir WHERE yan tümcesi. WHERE yan tümcesi hakkında daha fazla bilgi için bkz. SELECT sözdizimi. WHERE yan tümcesi eklemezseniz tablodaki tüm veriler silinir.

  • Örnekler

    • Örnek 1: acid_delete adlı bölümlenmemiş bir tablo oluşturun, veri aktarın ve ardından belirtilen bir koşulu sağlayan satırları silmek için DELETE işlemini çalıştırın. Örnek komutlar aşağıdadır:

      -- Create a Transactional table named acid_delete.
      CREATE TABLE IF NOT EXISTS acid_delete (id BIGINT) TBLPROPERTIES ("transactional"="true");
      
      -- Insert data.
      INSERT OVERWRITE TABLE acid_delete VALUES (1), (2), (3), (2);
      
      -- View the inserted data.
      SELECT * FROM acid_delete;
      
      +------------+
      | id         |
      +------------+
      | 1          |
      | 2          |
      | 3          |
      | 2          |
      +------------+
      
      -- Delete rows where id is 2. If you run this command on the MaxCompute client (odpscmd), you must enter yes or no to confirm.
      DELETE FROM acid_delete WHERE id = 2;
      -- The following command is equivalent to the one above.
      DELETE FROM acid_delete ad WHERE ad.id = 2;
      
      -- View the result. The table now contains only data for 1 and 3.
      SELECT * FROM acid_delete;
      
      +------------+
      | id         |
      +------------+
      | 1          |
      | 3          |
      +------------+
    • Örnek 2: acid_delete_pt adlı bölümlenmiş bir tablo oluşturun, veri aktarın ve ardından belirtilen bir koşulu sağlayan satırları silmek için DELETE işlemini çalıştırın. Örnek komutlar aşağıdadır:

      -- Create a Transactional table named acid_delete_pt.  
      CREATE TABLE IF NOT EXISTS acid_delete_pt (id BIGINT) PARTITIONED BY (ds STRING) TBLPROPERTIES ("transactional"="true");
      
      -- Add partitions.
      ALTER TABLE acid_delete_pt ADD IF NOT EXISTS PARTITION (ds = '2019');
      ALTER TABLE acid_delete_pt ADD IF NOT EXISTS PARTITION (ds = '2018');
      
      -- Insert data.
      INSERT OVERWRITE TABLE acid_delete_pt PARTITION (ds = '2019') VALUES (1), (2), (3);
      INSERT OVERWRITE TABLE acid_delete_pt PARTITION (ds = '2018') VALUES (1), (2), (3);
      
      -- View the inserted data.
      SELECT * FROM acid_delete_pt;
      
      +------------+------------+
      | id         | ds         |
      +------------+------------+
      | 1          | 2018       |
      | 2          | 2018       |
      | 3          | 2018       |
      | 1          | 2019       |
      | 2          | 2019       |
      | 3          | 2019       |
      +------------+------------+
      
      -- Delete data where the partition is 2019 and id is 2. If you run this command on the MaxCompute client (odpscmd), you must enter yes or no to confirm.
      DELETE FROM acid_delete_pt WHERE ds = '2019' AND id = 2;
      
      -- View the result. The data where the partition is 2019 and id is 2 has been deleted.
      SELECT * FROM acid_delete_pt;
      
      +------------+------------+
      | id         | ds         |
      +------------+------------+
      | 1          | 2018       |
      | 2          | 2018       |
      | 3          | 2018       |
      | 1          | 2019       |
      | 3          | 2019       |
      +------------+------------+
    • Örnek 3: acid_delete_t adlı bir hedef tablo ve bununla ilişkili acid_delete_s adlı bir tablo oluşturun. Ardından, bir birleştirme işlemi aracılığıyla belirtilen bir koşulu sağlayan satırları silin. Örnek komutlar aşağıdadır:

      -- Create a target Transactional table named acid_delete_t and an associated table named acid_delete_s. 
      CREATE TABLE IF NOT EXISTS acid_delete_t (id INT, value1 INT, value2 INT) TBLPROPERTIES ("transactional"="true");
      CREATE TABLE IF NOT EXISTS acid_delete_s (id INT, value1 INT, value2 INT);
      
      -- Insert data.
      INSERT OVERWRITE TABLE acid_delete_t VALUES (2, 20, 21), (3, 30, 31), (4, 40, 41);
      INSERT OVERWRITE TABLE acid_delete_s VALUES (1, 100, 101), (2, 200, 201), (3, 300, 301);
      
      -- Delete rows from the acid_delete_t table where the id does not match an id in the acid_delete_s table. If you run this command on the MaxCompute client (odpscmd), you must enter yes or no to confirm.
      DELETE FROM acid_delete_t WHERE NOT EXISTS (SELECT * FROM acid_delete_s WHERE acid_delete_t.id = acid_delete_s.id);
      -- The following command is equivalent to the one above.
      DELETE FROM acid_delete_t a WHERE NOT EXISTS (SELECT * FROM acid_delete_s b WHERE a.id = b.id);
      
      -- View the result. The table now contains only data for id 2 and 3.
      SELECT * FROM acid_delete_t;
      
      +------------+------------+------------+
      | id         | value1     | value2     |
      +------------+------------+------------+
      | 2          | 20         | 21         |
      | 3          | 30         | 31         |
      +------------+------------+------------+
    • Örnek 4: mf_dt adlı bir Delta Tablosu oluşturun, veri aktarın ve ardından belirtilen bir koşulu sağlayan satırları silmek için DELETE işlemini çalıştırın. Örnek komutlar aşağıdadır:

      -- Create a target Delta Table named mf_dt. 
      CREATE TABLE IF  NOT EXISTS mf_dt (pk BIGINT  NOT NULL PRIMARY KEY, 
                        val  BIGINT NOT NULL) 
                        PARTITIONED BY(dd STRING, hh STRING) 
                        tblproperties ("transactional"="true");
      
      -- Insert data.
      INSERT OVERWRITE TABLE mf_dt PARTITION (dd='01', hh='02') VALUES (1, 1), (2, 2), (3, 3);
      
      -- View the inserted data.                 
      SELECT * FROM mf_dt WHERE dd='01' AND hh='02';
      
      -- The following result is returned:
      +------------+------------+----+----+
      | pk         | val        | dd | hh |
      +------------+------------+----+----+
      | 1          | 1          | 01 | 02 |
      | 3          | 3          | 01 | 02 |
      | 2          | 2          | 01 | 02 |
      +------------+------------+----+----+
      
      -- Delete data where the partition is 01 and 02, and val is 2.
      DELETE FROM mf_dt WHERE val = 2  AND dd='01' AND hh='02';
      
      -- View the result. The table now contains only data where val is 1 and 3.
      SELECT * FROM mf_dt WHERE dd='01' AND hh='02';
      
      -- The following result is returned:
      +------------+------------+----+----+
      | pk         | val        | dd | hh |
      +------------+------------+----+----+
      | 1          | 1          | 01 | 02 |
      | 3          | 3          | 01 | 02 |
      +------------+------------+----+----+

Sütun verilerini temizleme

Standart bir tablodaki sütunlardaki verileri temizlemek için CLEAR COLUMN komutunu kullanabilirsiniz. Bu işlem, artık kullanılmayan verileri diskten siler ve sütun değerlerini NULL olarak ayarlar; bu da depolama maliyetlerini azaltmaya yardımcı olur.

  • Sözdizimi

    ALTER TABLE <table_name> 
      [PARTITION ( <pt_spec>[, <pt_spec>....] )] 
      CLEAR COLUMN column1[, column2, column3, ...]
      [WITHOUT TOUCH];
  • Parametreler


    Parametre


    Açıklama


    table_name


    Sütun verilerini temizlemek istediğiniz tablonun adı.


    column1 , column2 ...


    Verilerini temizlemek istediğiniz sütunların adları.


    PARTITION


    Bölümü belirtir. Belirtilmezse işlem tüm bölümlere uygulanır.


    pt_spec


    Bölüm açıklaması; biçimi (partition_col1 = PARTITION_col_value1, PARTITION_col2 = PARTITION_col_value2, ...) şeklindedir.


    WITHOUT TOUCH


    Belirtilirse LastDataModifiedTime güncellenmez. Belirtilmezse LastDataModifiedTime güncellenir.

    Not

    Şu anda varsayılan olarak WITHOUT TOUCH belirtilir. Gelecek bir sürümde, WITHOUT TOUCH belirtilmeden sütun verilerini temizleme davranışı desteklenecektir. Bu, WITHOUT TOUCH belirtilmezse LastDataModifiedTime öğesinin güncelleneceği anlamına gelir.

  • Sınırlamalar

    • NOT NULL kısıtlamasına sahip sütunlarda sütun temizleme işlemi gerçekleştiremezsiniz. NOT NULL kısıtlamasını manuel olarak kaldırabilirsiniz:

      ALTER TABLE <table_name> change COLUMN <old_col_name> NULL;
    • ACID tabloları için sütun verilerinin temizlenmesi desteklenmez.

    • Kümelendirilmiş tablolar için sütun verilerinin temizlenmesi desteklenmez.

    • İç içe geçmiş türler içinde sütun verilerinin temizlenmesi desteklenmez.

    • Tüm sütunların temizlenmesi desteklenmez. DROP TABLE komutu daha iyi performansla aynı etkiyi sağlar.

  • Dikkat edilecek noktalar

    • CLEAR COLUMN işlemi tablonun Archive özelliğini değiştirmez.

    • İç içe geçmiş bir tür sütununda yapılan CLEAR COLUMN işlemi başarısız olabilir.

      Bu hata, iç içe geçmiş türler için sütunlu depolama devre dışı bırakılırken sütunlu iç içe geçmiş türler içeren bir tabloda CLEAR COLUMN işlemi gerçekleştirirseniz oluşur.

    • CLEAR COLUMN komutu çevrimiçi Depolama Hizmetine bağlıdır. İş hacminin yüksek olduğu dönemlerde kuyruğa alınması gerekiyorsa görev yavaş olabilir.

    • CLEAR COLUMN işlemi verileri okumak ve yazmak için hesaplama kaynakları gerektirir. Abonelik kullanıcıları için bu işlem hesaplama kaynaklarını tüketir. Kullandıkça öde kullanıcıları için bir SQL işiyle aynı ücretlere tabidir. (Bu özellik şu anda davetli ön izleme aşamasındadır ve geçici olarak ücretsizdir.)

  • Örnekler

    • -- Create a table. 
      CREATE TABLE IF  NOT EXISTS mf_cc(key STRING, 
           value STRING, 
           a1 BIGINT , 
           a2 BIGINT , 
           a3 BIGINT , 
           a4 BIGINT)  
           PARTITIONED BY(ds STRING, hr STRING);
                       
      -- Add a partition.
      ALTER TABLE mf_cc ADD IF  NOT EXISTS PARTITION (ds='20230509', hr='1641');
      
      -- Insert data.
      INSERT INTO mf_cc PARTITION (ds='20230509', hr='1641') 
           VALUES("key","value",1,22,3,4);
           
      -- Query data.     
      SELECT * FROM mf_cc WHERE ds='20230509' AND  hr='1641';
      -- The following result is returned:
      +-----+-------+------------+------------+--------+------+---------+-----+
      | key | value | a1         | a2         | a3     | a4   | ds      | hr  |
      +-----+-------+------------+------------+--------+------+---------+-----+
      | key | value | 1          | 22         | 3      | 4    | 20230509| 1641|
      +-----+-------+------------+------------+--------+------+---------+-----+
      -- Clear column data.
      ALTER TABLE mf_cc PARTITION(ds='20230509', hr='1641') 
                        CLEAR COLUMN key,a1 
          WITHOUT TOUCH;
      -- Query data.     
      SELECT * FROM mf_cc WHERE ds='20230509' AND  hr='1641';
      -- The following result is returned. The data in the key and a1 columns has become null.
      +-----+-------+------------+------------+--------+------+---------+-----+
      | key | value | a1         | a2         | a3     | a4   | ds      | hr  |
      +-----+-------+------------+------------+--------+------+---------+-----+
      | null| value | null       | 22         | 3      | 4    | 20230509| 1641|
      +-----+-------+------------+------------+--------+------+---------+-----+
    • Aşağıdaki grafikte, CLEAR COLUMN komutu kullanılarak her sütun temizlendiğinde lineitem tablosunun (AliORC biçiminde) toplam depolama boyutundaki değişiklik gösterilmektedir. lineitem tablosu BIGINT, DECIMAL, CHAR, DATE ve VARCHAR dahil olmak üzere çeşitli türlerde 16 sütuna sahiptir.image.png

      Gördüğünüz gibi, tablonun 16 sütunu CLEAR COLUMN komutuyla sırayla NULL olarak ayarlandıktan sonra toplam depolama alanı %99,97 oranında azalmıştır (başlangıçtaki 186.783.526 bayttan 236.715 bayta).

      Not
      • CLEAR COLUMN işlemiyle tasarruf edilen alan miktarı, sütunun veri türüne ve gerçek depolanan değerlerine bağlıdır. Örneğin, DECIMAL türündeki l_extendedprice sütununun temizlenmesi alanın %24,2'sini (146.538.799 bayttan 111.138.117 bayta) tasarruf etmiş olup bu ortalamanın oldukça üzerindedir.

      • Tüm sütunlar NULL olarak ayarlandığında tablo boyutu 0 değil, 236.715 bayttır. Bunun nedeni, tablonun dosya yapısının hala mevcut olmasıdır. NULL alanlar küçük miktarda depolama alanı kaplar ve sistemin dosya altbilgi bilgilerini de tutması gerekir.

Veri güncelleme

UPDATE işlemi, bir Transactional tablo veya Delta Tablosundaki satırlar için bir veya daha fazla sütundaki değerleri günceller.

  • Sözdizimi

    -- Method 1
    UPDATE <table_name> [[AS] alias] SET <col1_name> = <value1> [, <col2_name> = <value2> ...] [WHERE <where_condition>];
    
    -- Method 2
    UPDATE <table_name> [[AS] alias] SET (<col1_name> [, <col2_name> ...]) = (<value1> [, <value2> ...]) [WHERE <where_condition>];
    
    -- Method 3
    UPDATE <table_name> [[AS] alias]
        SET <col1_name> = <value1> [, <col2_name> = <value2>, ...]
        [FROM <additional_tables>]
        [WHERE <where_condition>];
  • Parametreler

    • table_name: Gerekli. UPDATE işlemi için Transactional tablo veya Delta Tablosunun adı.

    • alias: İsteğe bağlı. Tablo için takma ad.

    • col1_name, col2_name: Gerekli. Değiştirilecek sütunların adları. En az bir sütunu güncellemeniz gerekir.

    • value1, value2: Gerekli. Sütunlar için yeni değerler. En az bir sütun değerini güncellemeniz gerekir.

    • where_condition: İsteğe bağlı. Verileri filtrelemek için bir WHERE yan tümcesi. WHERE yan tümcesi hakkında daha fazla bilgi için bkz. SELECT sözdizimi. WHERE yan tümcesi eklemezseniz tablodaki tüm veriler güncellenir.

    • additional_tables: İsteğe bağlı. FROM yan tümcesi.

      UPDATE deyimi, UPDATE deyimini basitleştirebilen FROM yan tümcesini destekler. Aşağıdaki tabloda FROM yan tümcesi kullanan bir UPDATE deyimi ile kullanmayan bir deyim karşılaştırılmaktadır.

      Senaryo

      Örnek kod

      FROM yan tümcesi olmadan

      UPDATE target SET v = 
        (SELECT MIN(v) FROM src GROUP BY k WHERE target.k = src.key)
        WHERE target.k IN (SELECT k FROM src);

      FROM yan tümcesi ile

      UPDATE target SET v = b.v
        FROM (SELECT k, MIN(v) AS v FROM src GROUP BY k) b
        WHERE target.k = b.k;

      Kod örneklerinde gösterildiği gibi:

      • Hedef tablodaki bir satırı kaynak tablodan gelen birden çok satır kullanarak güncellerken sistem hangi kaynak satırın kullanılacağını bilmediğinden kaynak verilerin benzersiz olduğundan emin olmak için bir toplama işlemi kullanmanız gerekir. FROM yan tümcesi kullanmayan sözdizimi daha az özlüdür. FROM yan tümceli sözdizimi daha basit ve anlaşılması daha kolaydır.

      • Bir birleştirme güncellemesi gerçekleştirirken yalnızca verilerin kesişimini güncellemek istiyorsanız FROM yan tümcesi kullanmayan sözdizimi ekstra bir WHERE koşulu gerektirir ve FROM yan tümcesi kullanan sözdizimine kıyasla daha az özlüdür.

  • Örnekler

    • Örnek 1: acid_update adlı bölümlenmemiş bir tablo oluşturun, veri aktarın ve ardından belirtilen bir koşulu sağlayan satırların sütunlarını güncellemek için UPDATE işlemini çalıştırın. Örnek komutlar aşağıdadır:

      -- Create a Transactional table named acid_update.  
      CREATE TABLE IF  NOT EXISTS acid_update(id BIGINT) tblproperties ("transactional"="true");
      
      -- Insert data.
      INSERT OVERWRITE TABLE acid_update VALUES(1),(2),(3),(2);
      
      -- View the inserted data.
      SELECT * FROM acid_update; 
      
      -- The following result is returned:
      +------------+
      | id         |
      +------------+
      | 1          |
      | 2          |
      | 3          |
      | 2          |
      +------------+
      
      -- Update the id value to 4 for all rows where id is 2.
      UPDATE acid_update SET id = 4 WHERE id = 2; 
      
      -- View the update result. 2 has been updated to 4.
      SELECT * FROM acid_update; 
      
      -- The following result is returned:
      +------------+
      | id         |
      +------------+
      | 1          |
      | 3          |
      | 4          |
      | 4          |
      +------------+
    • Örnek 2: acid_update adlı bölümlenmiş bir tablo oluşturun, veri aktarın ve ardından belirtilen bir koşulu sağlayan satırların sütunlarını güncellemek için UPDATE işlemini çalıştırın. Örnek komutlar aşağıdadır:

      -- Create a Transactional table named acid_update_pt. 
      CREATE TABLE IF  NOT EXISTS acid_update_pt(id BIGINT) PARTITIONED BY(ds STRING) tblproperties ("transactional"="true");
      
      -- Add a partition.
      ALTER TABLE acid_update_pt ADD IF  NOT EXISTS PARTITION (ds= '2019');
      
      -- Insert data.
      INSERT OVERWRITE TABLE acid_update_pt PARTITION (ds='2019') VALUES(1),(2),(3);
      
      -- View the inserted data.
      SELECT * FROM acid_update_pt WHERE ds = '2019'; 
      
      -- The following result is returned:
      +------------+------------+
      | id         | ds         |
      +------------+------------+
      | 1          | 2019       |
      | 2          | 2019       |
      | 3          | 2019       |
      +------------+------------+
      
      -- Update a column in a specified row. Set the id value to 4 for all rows where the partition is 2019 and id is 2.
      UPDATE acid_update_pt SET id = 4 WHERE ds = '2019' AND id = 2; 
      
      -- View the update result. 2 has been updated to 4.
      SELECT * FROM acid_update_pt WHERE ds = '2019';
      
      -- The following result is returned:
      +------------+------------+
      | id         | ds         |
      +------------+------------+
      | 4          | 2019       |
      | 1          | 2019       |
      | 3          | 2019       |
      +------------+------------+
    • Örnek 3: Aynı anda birden çok sütun değerini güncellemek için acid_update_t adlı bir hedef tablo ve acid_update_s adlı ilişkili bir tablo oluşturun. Örnek komutlar aşağıdadır:

      -- Create a target Transactional table to be updated, named acid_update_t, and an associated table named acid_update_s.
      CREATE TABLE IF  NOT EXISTS acid_update_t(id INT,value1 INT,value2 INT) tblproperties ("transactional"="true");
      CREATE TABLE IF  NOT EXISTS acid_update_s(id INT,value1 INT,value2 INT); 
      
      -- Insert data.
      INSERT OVERWRITE TABLE acid_update_t VALUES(2,20,21),(3,30,31),(4,40,41);
      INSERT OVERWRITE TABLE acid_update_s VALUES(1,100,101),(2,200,201),(3,300,301);
      
      -- Method 1: Update with constants.
      UPDATE acid_update_t SET (value1, value2) = (60,61);
      -- Query the result data in the target table for Method 1.
      SELECT * FROM acid_update_t;
      
      -- The following result is returned:
      +------------+------------+------------+
      | id         | value1     | value2     |
      +------------+------------+------------+
      | 2          | 60         | 61         |
      | 3          | 60         | 61         |
      | 4          | 60         | 61         |
      +------------+------------+------------+
      
      -- Method 2: Join update. The rule is a left join from acid_update_t to acid_update_s.
      UPDATE acid_update_t SET (value1, value2) = (SELECT value1, value2 FROM acid_update_s WHERE acid_update_t.id = acid_update_s.id);
      -- Query the result data in the target table for Method 2.
      SELECT * FROM acid_update_t;
      
      -- The following result is returned:
      +------------+------------+------------+
      | id         | value1     | value2     |
      +------------+------------+------------+
      | 2          | 200        | 201        |
      | 3          | 300        | 301        |
      | 4          | NULL       | NULL       |
      +------------+------------+------------+
      
      -- Method 3 (update based on the result of Method 2): Join update. The rule is to add a filter condition to update only the intersection.
      UPDATE acid_update_t SET (value1, value2) = (SELECT value1, value2 FROM acid_update_s WHERE acid_update_t.id = acid_update_s.id) WHERE acid_update_t.id IN (SELECT id FROM acid_update_s);
      -- Query the result data in the target table for Method 3.
      SELECT * FROM acid_update_t;
      
      -- The following result is returned:
      +------------+------------+------------+
      | id         | value1     | value2     |
      +------------+------------+------------+
      | 2          | 200        | 201        |
      | 3          | 300        | 301        |
      | 4          | NULL       | NULL       |
      +------------+------------+------------+
      
      -- Method 4 (update based on the result of Method 3): Join update with aggregate results.
      UPDATE acid_update_t SET (id, value1, value2) = (SELECT id, MAX(value1),MAX(value2) FROM acid_update_s WHERE acid_update_t.id = acid_update_s.id GROUP BY acid_update_s.id) WHERE acid_update_t.id IN (SELECT id FROM acid_update_s);
      -- Query the result data in the target table for Method 4.
      SELECT * FROM acid_update_t;
      
      -- The following result is returned:
      +------------+------------+------------+
      | id         | value1     | value2     |
      +------------+------------+------------+
      | 2          | 200        | 201        |
      | 3          | 300        | 301        |
      | 4          | NULL       | NULL       |
      +------------+------------+------------+
    • Örnek 4: İki tabloyu içeren basit bir birleştirme sorgusu. Örnek komutlar aşağıdadır:

      -- Create a target table for update, acid_update_t, and an associated table, acid_update_s. 
      CREATE TABLE IF  NOT EXISTS acid_update_t(id BIGINT,value1 BIGINT,value2 BIGINT) tblproperties ("transactional"="true");
      CREATE TABLE IF  NOT EXISTS acid_update_s(id BIGINT,value1 BIGINT,value2 BIGINT);
      
      -- Insert data.
      INSERT OVERWRITE TABLE acid_update_t VALUES(2,20,21),(3,30,31),(4,40,41);
      INSERT OVERWRITE TABLE acid_update_s VALUES(1,100,101),(2,200,201),(3,300,301);
      
      -- Query data from the acid_update_t table.
      SELECT * FROM acid_update_t;
      -- The following result is returned:
      +------------+------------+------------+
      | id         | value1     | value2     |
      +------------+------------+------------+
      | 2          | 20         | 21         |
      | 3          | 30         | 31         |
      | 4          | 40         | 41         |
      +------------+------------+------------+
      
      -- Query data from the acid_update_s table.
      SELECT * FROM acid_update_s;
      -- The following result is returned:
      +------------+------------+------------+
      | id         | value1     | value2     |
      +------------+------------+------------+
      | 1          | 100        | 101        |
      | 2          | 200        | 201        |
      | 3          | 300        | 301        |
      +------------+------------+------------+
      
      -- Join update. Add a filter condition to the target table to update only the intersection.
      UPDATE acid_update_t SET value1 = b.value1, value2 = b.value2
      FROM acid_update_s b WHERE acid_update_t.id = b.id;
      -- The following command is equivalent to the one above.
      UPDATE acid_update_t a SET a.value1 = b.value1, a.value2 = b.value2 
      FROM acid_update_s b WHERE a.id = b.id;
      
      -- View the update result. 20 is updated to 200, 21 to 201, 30 to 300, and 31 to 301.
      SELECT * FROM acid_update_t;
      -- The following result is returned:
      +------------+------------+------------+
      | id         | value1     | value2     |
      +------------+------------+------------+
      | 4          | 40         | 41         |
      | 2          | 200        | 201        |
      | 3          | 300        | 301        |
      +------------+------------+------------+                          
    • Örnek 5: Birden çok tabloyu içeren karmaşık bir birleştirme sorgusu. Örnek komutlar aşağıdadır:

      -- Create a target table for update, acid_update_t, and an associated table, acid_update_s. 
      CREATE TABLE IF  NOT EXISTS acid_update_t(id BIGINT,value1 BIGINT,value2 BIGINT) tblproperties ("transactional"="true");
      CREATE TABLE IF  NOT EXISTS acid_update_s(id BIGINT,value1 BIGINT,value2 BIGINT);
      CREATE TABLE IF  NOT EXISTS acid_update_m(id BIGINT,value1 BIGINT,value2 BIGINT);
      
      -- Insert data.
      INSERT OVERWRITE TABLE acid_update_t VALUES(2,20,21),(3,30,31),(4,40,41),(5,50,51);
      INSERT OVERWRITE TABLE acid_update_s VALUES (1,100,101),(2,200,201),(3,300,301),(4,400,401),(5,500,501);
      INSERT OVERWRITE TABLE acid_update_m VALUES(3,30,101),(4,400,201),(5,300,301);
      
      -- Query data from the acid_update_t table.
      SELECT * FROM acid_update_t;
      -- The following result is returned:
      +------------+------------+------------+
      | id         | value1     | value2     |
      +------------+------------+------------+
      | 2          | 20         | 21         |
      | 3          | 30         | 31         |
      | 4          | 40         | 41         |
      | 5          | 50         | 51         |
      +------------+------------+------------+
      
      -- Query data from the acid_update_s table.
      SELECT * FROM acid_update_s;
      -- The following result is returned:
      +------------+------------+------------+
      | id         | value1     | value2     |
      +------------+------------+------------+
      | 1          | 100        | 101        |
      | 2          | 200        | 201        |
      | 3          | 300        | 301        |
      | 4          | 400        | 401        |
      | 5          | 500        | 501        |
      +------------+------------+------------+
      
      -- Query data from the acid_update_m table.
      SELECT * FROM acid_update_m;
      -- The following result is returned:
      +------------+------------+------------+
      | id         | value1     | value2     |
      +------------+------------+------------+
      | 3          | 30         | 101        |
      | 4          | 400        | 201        |
      | 5          | 300        | 301        |
      +------------+------------+------------+
      
      -- Join update, and filter both the source and target tables in the WHERE clause.
      UPDATE acid_update_t 
      SET value1 = acid_update_s.value1, value2 = acid_update_s.value2 
      FROM acid_update_s 
      WHERE acid_update_t.id = acid_update_s.id 
      AND acid_update_s.id > 2 
      AND acid_update_t.value1 NOT IN 
      (SELECT value1 FROM acid_update_m WHERE id = acid_update_t.id) 
      AND acid_update_s.value1 NOT IN 
      (SELECT value1 FROM acid_update_m WHERE id = acid_update_s.id);
      
      -- View the update result. Only the data in the acid_update_t table with id 5 meets the condition. The corresponding value1 is updated to 500, and value2 is updated to 501.
      SELECT * FROM acid_update_t;
      -- The following result is returned:
      +------------+------------+------------+
      | id         | value1     | value2     |
      +------------+------------+------------+
      | 5          | 500        | 501        |
      | 2          | 20         | 21         |
      | 3          | 30         | 31         |
      | 4          | 40         | 41         |
      +------------+------------+------------+
    • Örnek 6: Aşağıdaki komut, mf_dt adlı bir Delta tablosu oluşturmanın, veri aktarmanın ve belirtilen bir koşulu sağlayan satırları silmek için bir UPDATE işlemi yürütmenin bir örneğidir:

      -- Create a target Delta Table named mf_dt.
      CREATE TABLE IF  NOT EXISTS mf_dt (pk BIGINT  NOT NULL PRIMARY KEY, 
                        val  BIGINT NOT NULL) 
                        PARTITIONED BY(dd STRING, hh STRING) 
                        tblproperties ("transactional"="true");
      
      -- Insert data.
      INSERT OVERWRITE TABLE mf_dt PARTITION (dd='01', hh='02') 
                       VALUES (1, 1), (2, 2), (3, 3);
      
      -- View the inserted data.                 
      SELECT * FROM mf_dt WHERE dd='01' AND hh='02';
      -- The following result is returned:
      +------------+------------+----+----+
      | pk         | val        | dd | hh |
      +------------+------------+----+----+
      | 1          | 1          | 01 | 02 |
      | 3          | 3          | 01 | 02 |
      | 2          | 2          | 01 | 02 |
      +------------+------------+----+----+
      
      -- Update a column in a specified row. Set the val value to 30 for all rows where the partition is 01 and 02, and pk is 3.
      -- Method 1
      UPDATE mf_dt SET val = 30 WHERE pk = 3 AND dd='01' AND hh='02';
      
      -- Method 2
      UPDATE mf_dt SET val = delta.val 
                    FROM (SELECT pk, val FROM VALUES (3, 30) t (pk, val)) delta 
                    WHERE delta.pk = mf_dt.pk AND mf_dt.dd='01' AND mf_dt.hh='02';
      
      -- View the update result.
      SELECT * FROM mf_dt WHERE dd='01' AND hh='02';
      -- The following result is returned. The val value for the row with pk=3 is updated to 30.
      +------------+------------+----+----+
      | pk         | val        | dd | hh |
      +------------+------------+----+----+
      | 1          | 1          | 01 | 02 |
      | 3          | 30         | 01 | 02 |
      | 2          | 2          | 01 | 02 |
      +------------+------------+----+----+

Transactional tablo dosyalarını birleştirme

Bir Transactional tablonun alttaki fiziksel depolaması, doğrudan okunamayan temel dosyalardan ve Delta dosyalarından oluşur. Bir Transactional tablo üzerinde UPDATE veya DELETE işlemi çalıştırdığınızda temel dosyalar değiştirilmez. Bunun yerine Delta dosyaları eklenir. Bu, daha fazla güncelleme veya silme işlemi gerçekleştirdiğinizde tablonun daha fazla depolama alanı kapladığı anlamına gelir. Çok sayıda Delta dosyasının birikmesi depolama ve sonraki sorgu maliyetlerini artırabilir.

Aynı tablo veya bölüm üzerinde birden çok UPDATE veya DELETE işlemi çalıştırmak çok sayıda Delta dosyası oluşturur. Sistem verileri okurken hangi satırların güncellendiğini veya silindiğini belirlemek için bu Delta dosyalarını yüklemelidir. Çok sayıda Delta dosyası veri okuma performansını düşürebilir. Bu durumda depolamayı azaltmak ve veri okuma performansını artırmak için temel dosyaları ve Delta dosyalarını birleştirebilirsiniz.

  • Sözdizimi

    ALTER TABLE <table_name> [PARTITION (<partition_key> = '<partition_value>' [, ...])] compact {minor|major};
  • Parametreler

    Parametre

    Gerekli

    Açıklama

    table_name

    Evet

    Dosyalarını birleştirmek istediğiniz Transactional tablonun adı.

    partition_key

    Hayır

    Transactional tablo bölümlenmiş bir tabloysa bölüm anahtarı sütun adını belirtin.

    partition_value

    Hayır

    Transactional tablo bölümlenmiş bir tabloysa bölüm anahtarı sütunu için değeri belirtin.

    major|minor

    Evet

    Birini seçmeniz gerekir. Farklar şunlardır:

    minor: Yalnızca temel dosyaları ve bunların altındaki tüm Delta dosyalarını birleştirir, Delta dosyalarını ortadan kaldırır.

    major: Yalnızca temel dosyaları ve bunların altındaki tüm Delta dosyalarını birleştirerek Delta dosyalarını ortadan kaldırmakla kalmaz, ayrıca tablonun karşılık gelen temel dosyaları içindeki küçük dosyaları da birleştirir. Bir temel dosya küçükse (32 MB'den az) veya Delta dosyaları varsa bu, tablo üzerinde tekrar bir INSERT OVERWRITE işlemi çalıştırmaya eşdeğerdir. Ancak temel dosya yeterince büyükse (32 MB'a eşit veya bundan büyük) ve Delta dosyası yoksa yeniden yazılmaz.

  • Dikkat edilecek noktalar

    compact işlemi tarafından birleştirilen küçük dosyalar bir gün sonra silinir. Bu küçük dosyalara bağımlı bir geçmişi geri yüklemek için yerel yedekleme özelliğini kullanırsanız dosyalar eksik olduğu için kurtarma işlemi başarısız olur.

  • Örnekler

    • Örnek 1: acid_delete Transactional tablosu için dosyaları birleştirin. Örnek komut aşağıdadır:

      ALTER TABLE acid_delete compact minor; 

      Aşağıdaki sonuç döndürülür:

      Summary:
      Nothing found to merge, set odps.merge.cross.paths=true if cross path merge is permitted.
      OK
    • Örnek 2: acid_update_pt Transactional tablosu için dosyaları birleştirin. Örnek komut aşağıdadır:

      ALTER TABLE acid_update_pt PARTITION (ds = '2019') compact major; 

      Aşağıdaki sonuç döndürülür:

      Summary:
      table name: acid_update_pt /ds=2019  instance count: 2  run time: 6
        before merge, file count:        8  file size: 2613  file physical size: 7839
         after merge, file count:        2  file size: 679  file physical size: 2037
      
      OK

SSS

  • Sorun 1:

    • Sorun açıklaması: Bir UPDATE deyimi çalıştırdığımda ODPS-0010000:System internal error - fuxi job failed, caused by: Data Set should contain exactly one row hatası bildiriliyor.

    • Neden: Güncellenecek satırlar ile alt sorgu sonucundaki veriler arasında birebir karşılık yoktur. Sistem hangi satırın güncelleneceğini belirleyemez. Örnek bir komut aşağıdadır:

      UPDATE store SET (s_county, s_manager) = (SELECT d_country, d_manager FROM store_delta sd WHERE sd.s_store_sk = store.s_store_sk) WHERE s_store_sk IN (SELECT s_store_sk FROM store_delta);

      SELECT d_country, d_manager FROM store_delta sd WHERE sd.s_store_sk = store.s_store_sk alt sorgusu store_delta ile birleştirmek için kullanılır ve store'u güncellemek üzere store_delta'dan alınan veriler kullanılır. Store tablosundaki s_store_sk sütununda [1, 2, 3] olmak üzere üç satır veri bulunduğunu varsayalım. Store_delta tablosundaki s_store_sk sütununda [1, 1] olmak üzere iki satır veri varsa birebir karşılık yoktur ve yürütme başarısız olur.

    • Çözüm: Güncellenecek satırların alt sorgu sonucundaki verilerle birebir karşılık geldiğinden emin olun.

  • Sorun 2:

    • Sorun açıklaması: DataWorks DataStudio'da compact komutunu çalıştırdığımda ODPS-0130161:[1,39] Parse exception - invalid token 'minor', expect one of 'StringLiteral','DoubleQuoteStringLiteral' hatası bildiriliyor.

    • Neden: DataWorks için özel kaynak grubundaki MaxCompute istemci sürümü compact komutunu desteklemiyor.

    • Çözüm: DataWorks DingTalk grubu aracılığıyla teknik destek ekibiyle iletişime geçerek özel kaynak grubundaki MaxCompute istemci sürümünü yükseltin.