2013-11-15 2 views
1

Когда я запрашиваю таблицу бронирования через JPA/EclipseLink и ищу конкретное местоID, текущий существующий индекс myindex не используется. Sybase решает сделать сканирование таблицы.EclipseLink Sybase: Существующий индекс не используется

Когда я копирую sql из файла журнала Glassfish в sql-редактор и запускаю его там, он использует индекс. ????

Упрощенная SQL:

create table pub.BOOKING(
    bookID numeric(10) identity, 
    placeID smallint not null 
) 

create index idx_BOOKING_PLACEID on pub.BOOKING(placeID) 

** SHOWPLAN из Sybase ASE при работе от JPQL **

Die Art der Abfrage ist SELECT.   
VON TABELLE pub.BOOKING       
Verschachtelte Iteration.     
Tabellen-Scan.        
Vorwärts-Scan.        
Positionierung am Tabellenanfang.   
Parallel mit einem 5-Weg-Hash-Scan ausgefü 
Für die Datenseiten wird eine I/O-Größe vo 
Mit LRU Pufferersetzungsstrategie für Date 
Parallele Netzpufferzusammenführung.  

** JPQL Запрос **

Placement p = em_local.find(Placement.class, 207); 
TypedQuery<Booking> query = em_local.createQuery("select b from Booking b where b.placement = :place", Booking.class); 
query.setParameter("place", p); 
List<Booking> list = query.getResultList(); 

** SHOWPLAN из Sybase ASE при работе в редакторе sql **

 VON TABELLE 
     pub.BOOKING 
    Verschachtelte Iteration. 
    Index: idx_BOOKING_PLACEID 
    Vorwärts-Scan. 
    Positionierung durch Schlüssel. 
    Schlüssel sind: 
     placeID AUFST 
    Parallel mit einem 5-Weg-Hash-Scan ausgeführt. 
    Für die Index-Blattebenen wird eine I/O-Größe von 2 KByte verwendet. 
    Mit LRU Pufferersetzungsstrategie für Index-Blattseiten. 
    Für die Datenseiten wird eine I/O-Größe von 2 KByte verwendet. 
    Mit LRU Pufferersetzungsstrategie für Datenseiten. 

** Запрошенного Выбрать из логфайла **

20131118 08:44:59,845 FINE  sql  SELECT bookID, placeID FROM pub.BOOKING WHERE (placeID = ?)  bind => [207] 

** После некоторых исследований **

Похоже SMALLINT типа данных от Sybase является проблемой здесь.

EclipseLink запросы как это:

declare @p0 int 
select @p0 = 5 
select * from pub.BOOKING where placeID = @p0 

Если я пишу объявить @ p0 SMALLINT индекс используется. Если я пишу declare @ p0 int, индекс не используется.

Так что, я думаю, JPA отображает Integer в int. И это вызывает проблему.

Как я могу сказать JPA использовать smallint для этого столбца?

+0

Put следующие свойства в вашем 'настойчивостью.xml': Затем покажите нам, как Eclipselink переводит ваш запрос JPQL на SQL. – hgoebl

+0

Я добавил его в вопрос выше –

+0

Странный. Иногда оптимизатор не использует индекс, потому что таблица слишком короткая (например, имеет только 15 записей) или распределение (разные значения) не идеально подходит для использования индекса (например, у вас есть столбец, который имеет только два разных значения) m 'и' f ', и оба они покрывают ~ 50% строк). Используете ли вы ту же базу данных для GlassFish и интерактивного sql-редактора? Если да, я не могу вам помочь. – hgoebl

ответ

1

Проблема заключается в типе данных Smallint.

Я использовал Integer в классе Entity для доступа к нему. Это позволит JPA запрос так:

declare @p0 int 
select @p0 = 5 
select bookID, placeID from pub.BOOKING where placeID = @p0 

Sybase этого давайте решим, что «где» утверждение не является стандартной Довод (SARG). Это означает, что он не может использовать соответствующий индекс, потому что тип данных индекса равен 2 байтам, а параметр - 4 байта.

Использование короткого типа данных в Entity решило проблему.

** Некоторые запросы я сделал на Sybase ASE, чтобы выяснить, что неправильно **

Вы должны установить MDA Особенность Sybase первой.

Это показывает, если у вас есть сканирование таблицы:

select * 
from master.dbo.monSysPlanText 
order by SPID, BatchID, SequenceNumber 

Это шоу вы, что запрос JPA действительно отсылка к ASE:

select * 
from master.dbo.monSysSQLText