SQL Server ve Oracle ile çalışıyorum. Muhtemelen bazı istisnalar vardır, ancak bu platformlar için genel cevap, veri ve indekslerin aynı anda güncelleneceği yönündedir.
İşlemin sahibi olan oturum ve diğer oturumlar için dizinlerin güncelleştirilmesi arasında bir ayrım çizmenin yararlı olacağını düşünüyorum. Varsayılan olarak, diğer oturumlar işlem tamamlanana kadar güncellenmiş dizinleri görmez. Ancak, işlemin sahibi olan oturumda derhal güncellenen dizinler görüntülenir.
Bunu düşünmenin bir yolu için, birincil anahtarlı bir masada düşünün. SQL Server ve Oracle'da bu bir dizin olarak uygulanır. Çoğu zaman INSERT
birincil anahtarı ihlal edecek bir an yapılırsa hemen bir hata olmasını istiyoruz . Bunun olabilmesi için indeksin verilerle aynı zamanda güncellenmesi gerekir. Postgres gibi diğer platformların, yalnızca işlem tamamlandığında denetlenen ertelenmiş kısıtlamalara izin verdiğini unutmayın.
İşte genel bir durumu gösteren hızlı bir Oracle demosu:
CREATE TABLE X_TABLE (PK INT NULL, PRIMARY KEY (PK));
INSERT INTO X_TABLE VALUES (1);
INSERT INTO X_TABLE VALUES (1); -- no commit
İkinci INSERT
ifade bir hata verir:
SQL Hatası: ORA-00001: benzersiz kısıtlama (XXXXXX.SYS_C00384850) ihlal edildi
00001.
00000 - "benzersiz kısıtlama (% s.% S) ihlal edildi"
* Neden: Bir UPDATE veya INSERT deyimi yinelenen bir anahtar eklemeye çalıştı. DBMS MAC modunda yapılandırılmış Güvenilen Oracle için, farklı bir düzeyde yinelenen bir giriş varsa bu mesajı görebilirsiniz.
* Eylem: Benzersiz kısıtlamayı kaldırın veya anahtarı takmayın.
Aşağıdaki dizin güncelleme eylemini görmek isterseniz SQL Server'da basit bir demo. İlk önce bir milyon satır ve VAL
sütun üzerinde kümelenmemiş bir dizin içeren iki sütun tablosu oluşturun :
DROP TABLE IF EXISTS X_TABLE_IX;
CREATE TABLE X_TABLE_IX (
ID INT NOT NULL,
VAL VARCHAR(10) NOT NULL
PRIMARY KEY (ID)
);
CREATE INDEX X_INDEX ON X_TABLE_IX (VAL);
-- insert one million rows with N from 1 to 1000000
INSERT INTO X_TABLE_IX
SELECT N, N FROM dbo.Getnums(1000000);
Aşağıdaki sorgu kümelenmemiş dizini kullanabilir, çünkü dizin bu sorgu için bir kaplama dizinidir. Yürütmek için gereken tüm verileri içerir. Beklendiği gibi, iade alınmaz.
SELECT *
FROM X_TABLE_IX
WHERE VAL = 'A';
Şimdi bir işlem VAL
başlatalım ve tablodaki hemen hemen tüm satırlar için güncelleme yapalım :
BEGIN TRANSACTION
UPDATE X_TABLE_IX
SET VAL = 'A'
WHERE ID <> 1;
İşte bunun için sorgu planının bir parçası:
Kırmızı ile çevrelenmiş, kümelenmemiş dizine yapılan güncellemedir. Mavi daire içine alınmış, esasen tablonun verileri olan kümelenmiş dizine yapılan güncellemedir. İşlem yapılmamasına rağmen, verilerin ve dizinin sorgunun yürütülmesinin bir bölümünde güncellendiğini görüyoruz. Muhtemelen diğer faktörlerle birlikte verilerin boyutuna bağlı olarak bunu her zaman bir planda görmeyeceğinizi unutmayın.
İşlem hala tamamlanmadıysa, SELECT
sorguyu yukarıdan tekrar gözden geçirelim .
SELECT *
FROM X_TABLE_IX
WHERE VAL = 'A';
Sorgu iyileştirici yine de dizini kullanabiliyor ve bu sefer 999999 satırın döndürüleceğini tahmin ediyor. Sorguyu yürütmek beklenen sonucu döndürür.
Bu basit bir demodu ama umarım bazı şeyleri temizledi.
Bir kenara, bir endeksin hemen güncellenmediği iddia edilebilir birkaç durumun farkındayım. Bu, performans nedenleriyle yapılır ve son kullanıcı tutarsız verileri göremez. Örneğin, bazen siler SQL Server'daki bir dizine tam olarak uygulanmayacaktır. Bir arka plan işlemi çalışır ve sonunda verileri temizler. Merak ediyorsanız hayalet kayıtlarını okuyabilirsiniz .