Defining Indexes
CREATE/DROP INDEX gibi yaygın DDL komutlarına ek olarak dizinleri tanımlamak için Ignite'ın SQL API'lerini kullanabilirsiniz.
Ignite, her primary key ve affinity key alanı için otomatik olarak indexler oluşturur. Değer nesnesindeki bir alan üzerinde bir index tanımladığınızda, Ignite, indexlenmiş alandan ve cache’in primary keyinden oluşan bir composite index oluşturur. SQL açısından bu, indexin iki sütundan oluşacağı anlamına gelir: indexe eklemek istediğiniz sütun ve primary key sütunu.
Creating Indexes With SQL
CREATE INDEX bölümüne bakın.
Configuring Indexes Using Annotations
Indexler ve sorgulanabilir alanlar, [QuerySqlField]
attribute’u aracılığıyla koddan yapılandırılabilir. Aşağıdaki örnekte, Ignite SQL motoru id
ve salary
alanları için indexler oluşturacaktır.
- ⌨️ .NET Sample
class Person
{
// Indexed field. Will be visible to the SQL engine.
[QuerySqlField(IsIndexed = true)] public long Id;
//Queryable field. Will be visible to the SQL engine
[QuerySqlField] public string Name;
//Will NOT be visible to the SQL engine.
public int Age;
/** Indexed field sorted in descending order.
* Will be visible to the SQL engine. */
[QuerySqlField(IsIndexed = true, IsDescending = true)]
public float Salary;
}
Tür adı, SQL sorgularında tablo adı olarak kullanılır. Bu durumda tablomuzun adı Person
olacaktır (şema adı kullanımı ve tanımı Schemas bölümünde anlatılmıştır).
Hem id
hem de salary
indexli alanlardır. id
artan şekilde (varsayılan) ve salary
azalan şekilde sıralanacaktır.
Bir alanı indexe eklemek istemiyorsanız, ancak yine de SQL sorgularında kullanmanız gerekiyorsa, o zaman alana index = true
parametresi olmadan attribute eklenmelidir. Böyle bir alana sorgulanabilir alan denir. Yukarıdaki örnekte, name
sorgulanabilir bir alan olarak tanımlanmıştır.
Age
alanı ne sorgulanabilir ne de indexlenmiş bir alandır ve bu nedenle SQL sorgularından erişilemez.
İndexlenmiş alanları tanımladığınızda, indexlenmiş türleri kaydetmeniz gerekir.
Indexing Nested Objects
Nested nesnelerin alanları da ek attributelar kullanılarak indexe eklenebilir ve sorgulanabilir. Örneğin, bir alan olarak Address
nesnesine sahip bir Person
nesnesini düşünün:
- ⌨️ Java Sample
public class Person {
/** Indexed field. Will be visible for SQL engine. */
@QuerySqlField(index = true)
private long id;
/** Queryable field. Will be visible for SQL engine. */
@QuerySqlField
private String name;
/** Will NOT be visible for SQL engine. */
private int age;
/** Indexed field. Will be visible for SQL engine. */
@QuerySqlField(index = true)
private Address address;
}
Address
sınıfının yapısı şöyle görünebilir:
- ⌨️ Java Sample
public class Address {
/** Indexed field. Will be visible for SQL engine. */
@QuerySqlField (index = true)
private String street;
/** Indexed field. Will be visible for SQL engine. */
@QuerySqlField(index = true)
private int zip;
}
Yukarıdaki örnekte, @QuerySqlField(index = true)
annotation’u, Person
sınıfındaki Address
nesnesinin yanı sıra Address
sınıfının tüm alanlarında belirtilmiştir.
Bu, aşağıdaki gibi SQL sorgularını yürütmeyi mümkün kılar:
QueryCursor<List<?>> cursor = personCache.query(new SqlFieldsQuery( "select * from Person where street = 'street1'"));
SQL sorgusunun WHERE yan tümcesinde address.street
belirtmeniz gerekmediğini unutmayın. Bunun nedeni, Address
sınıfının alanlarının Person
tablosunda düzleştirilmesidir(flattened); bu, sorgulardaki Address
alanlarına doğrudan erişmemizi sağlar.
Nested nesneler için indexler oluşturursanız, tabloda UPDATE veya INSERT deyimlerini çalıştıramazsınız.
Registering Indexed Types
Indexlenmiş ve sorgulanabilir alanlar tanımlandıktan sonra ait oldukları nesne türleri ile birlikte SQL motorunda kaydedilmeleri gerekir.
Hangi türlerin indexe eklenmesi gerektiğini belirtmek için aşağıdaki örnekte gösterildiği gibi CacheConfiguration.setIndexedTypes()
yönteminde karşılık gelen key/value pairlerini iletin.
- ⌨️ .NET Sample
var ccfg = new CacheConfiguration
{
QueryEntities = new[]
{
new QueryEntity(typeof(long), typeof(Person))
}
};
Bu method yalnızca tür pairlerini kabul eder: biri key sınıf için, diğeri value sınıfı için. Primitive tipler boxed tipler olarak geçirilir.
*[QuerySqlField]
attribute’u ile işaretlenmiş tüm alanlara ek olarak, her tablo önceden tanımlanmış iki özel alana sahip olacaktır:_key
ve_val
, tüm key ve value nesnelerine bağlantıları temsil eder. Bu, örneğin, bunlardan biri primitive bir tür olduğunda ve değerine göre filtrelemek istediğinizde kullanışlıdır. Bunu yapmak için şöyle bir sorgu çalıştırın:SELECT * FROM Person WHERE _key = 100
.*
Ignite, Binary Nesneleri desteklediğinden, cluster node’larının sınıf yoluna index’e alınmış türden sınıflar eklemeye gerek yoktur. SQL sorgu motoru, indexe alınmış ve sorgulanabilir alanların değerlerini algılayarak nesne deserialization işleminden kaçınabilir.
Group Indexes
Karmaşık koşullara sahip sorguları hızlandırabilen çok alanlı bir index ayarlamak için bir [QuerySqlField.IndexGroups]
özelliğini kullanabilirsiniz. Bir alanın birden fazla grubun parçası olmasını istiyorsanız, IndexGroups
'a birden çok [QuerySqlField.IndexGroups]
özelliği ekleyebilirsiniz.
Örneğin, aşağıdaki Person
sınıfında, age_salary_idx
adlı, "0" grup düzeni ve azalan sıralama düzeni ile indexlenmiş bir gruba ait age
alanına sahibiz. Ayrıca aynı grupta, "3" grup düzeninde ve artan sıralama düzeninde salary
alanımız var. Ayrıca, salary
alanının kendisi tek sütunlu bir indextir(IndexGroups
bildirimine ek olarak index = true
parametresi belirtilir). Grup sırası belirli bir sayı olmak zorunda değildir. Yalnızca belirli bir grubun içindeki alanları sıralamak için gereklidir.
- ⌨️ .NET Sample
class Person
{
[QuerySqlField(IndexGroups = new[] {"age_salary_idx"})]
public int Age;
[QuerySqlField(IsIndexed = true, IndexGroups = new[] {"age_salary_idx"})]
public double Salary;
}
Configuring Indexes Using Query Entities
Indexler ve sorgulanabilir alanlar, Spring XML tabanlı yapılandırma için uygun olan org.apache.ignite.cache.QueryEntity sınıfı aracılığıyla da yapılandırılabilir.
Yukarıda attribute tabanlı yapılandırmanın bir parçası olarak açıklanan tüm kavramlar, QueryEntity tabanlı yaklaşım için de geçerlidir. Ayrıca, alanları [QuerySqlField]
attribute’u ile yapılandırılan ve CacheConfiguration.setIndexedTypes()
yöntemiyle kaydedilen türler, dahili olarak sorgu varlıklarına dönüştürülür.
Aşağıdaki örnek, tek bir alan indexi, grup indexleri ve sorgulanabilir alanların nasıl tanımlanacağını gösterir.
- ⌨️ .NET Sample
var cacheCfg = new CacheConfiguration
{
Name = "myCache",
QueryEntities = new[]
{
new QueryEntity
{
KeyType = typeof(long),
KeyFieldName = "id",
ValueType = typeof(dotnet_helloworld.Person),
Fields = new[]
{
new QueryField
{
Name = "id",
FieldType = typeof(long)
},
new QueryField
{
Name = "name",
FieldType = typeof(string)
},
new QueryField
{
Name = "salary",
FieldType = typeof(long)
},
},
Indexes = new[]
{
new QueryIndex("name"),
new QueryIndex(false, QueryIndexType.Sorted, new[] {"id", "salary"})
}
}
}
};
Ignition.Start(new IgniteConfiguration
{
CacheConfiguration = new[] {cacheCfg}
});
ValueType
'ın kısa adı, SQL sorgularında tablo adı olarak kullanılır. Bu durumda tablomuzun adı olacaktır.
QueryEntity
tanımlandıktan sonra, SQL sorgusunu aşağıdaki gibi yürütebilirsiniz:
SqlFieldsQuery qry = new SqlFieldsQuery("SELECT id, name FROM Person" + "WHERE id > 1500 LIMIT 10");
Configuring Index Inline Size
Uygun index satır içi boyutu, indexe alınmış alanlarda sorguları hızlandırmaya yardımcı olabilir. Uygun bir satır içi boyutun nasıl seçileceği hakkında bilgi için SQL Ayarlama kılavuzundaki ilgili bölüme bakın.
Çoğu durumda, yalnızca stringler veya arrayler gibi değişken uzunluklu alanlardaki indexler için satır içi boyutunu ayarlamanız gerekir. Varsayılan değer 10'dur.
Varsayılan değeri
- her index için ayrı ayrı satır içi boyut veya,
- belirli bir cache içindeki tüm indexler için
CacheConfiguration.sqlIndexMaxInlineSize
özelliği veya - Clusterdaki tüm indexler için
IGNITE_MAX_INDEX_PAYLOAD_SIZE
sistem özelliği
ayarlayarak değiştirebilirsiniz. Ayarlar, yukarıda listelenen sırayla uygulanır.
Ayrıca varsayılan değerin üzerine yazacak şekilde her index için satır içi boyutunu ayrı ayrı yapılandırabilirsiniz. Kullanıcı tanımlı bir index için index satır içi boyutunu ayarlamak üzere aşağıdaki yöntemlerden birini kullanın. Her durumda, değer bayt olarak ayarlanır.
- ⌨️ .NET Sample with Attribute
[QuerySqlField(IsIndexed = true, IndexInlineSize = 13)]
public string Country { get; set; } - ⌨️ .NET Sample with
QueryEntity
var qe = new QueryEntity
{
Indexes = new[]
{
new QueryIndex
{
InlineSize = 13
}
}
};
CREATE INDEX
komutunu kullanarak indexler oluşturursanız, satır içi boyutunu ayarlamak için INLINE_SIZE
seçeneğini kullanabilirsiniz. İlgili bölümdeki örneklere bakın;
create index country_idx on Person (country) INLINE_SIZE 13;
Custom Keys
Primary keyler için yalnızca önceden tanımlanmış SQL veri türlerini kullanırsanız, SQL şeması yapılandırmasıyla ek manipülasyon yapmanız gerekmez. Bu veri türleri, aşağıda listelendiği gibi GridQueryProcessor.SQL_TYPES
sabiti tarafından tanımlanır.
Önceden tanımlanmış SQL veri türleri şunları içerir:
char
veCharacter
dışındaki tüm primitive tipler ve wrapperlarıString
BigDecimal
byte[]
java.util.Date
,java.sql.Date
,java.sql.Timestamp
java.util.UUID
Ancak, özel bir karmaşık key uygulamaya karar verdiğinizde ve alanlarına DML ifadelerinden başvurduğunuzda, şunları yapmanız gerekir:
QueryEntity
'deki bu alanları, değer nesnesi için alanları ayarladığınız şekilde tanımlayın.- Key alanları value alanlarından ayırmak için yeni yapılandırma parametresi
QueryEntity.setKeyFields(..)
kullanın.
Aşağıdaki örnek bunun nasıl yapılacağını göstermektedir.
- ⌨️ .NET Sample