Einzelnen Beitrag anzeigen

ZOD

Registriert seit: 6. Mai 2009
97 Beiträge
 
#1

Index wird nicht verwendet

  Alt 21. Nov 2017, 13:27
Datenbank: Firebird • Version: 2.5 • Zugriff über: ISQL / ibexpert
Hallo Zusammen,

ich habe folgende Datenbanktabelle:

Code:
/******************************************************************************/
/****              Generated by IBExpert 21.11.2017 13:19:19               ****/
/******************************************************************************/

/******************************************************************************/
/****     Following SET SQL DIALECT is just for the Database Comparer     ****/
/******************************************************************************/
SET SQL DIALECT 3;



/******************************************************************************/
/****                                Tables                               ****/
/******************************************************************************/
CREATE GENERATOR G_TEST;

CREATE TABLE T_TEST (
    ID        INTEGER NOT NULL,
    NAME      VARCHAR(201),
    KEY_VALUE INTEGER
);


/******************************************************************************/
/****                             Primary keys                            ****/
/******************************************************************************/

ALTER TABLE T_TEST ADD CONSTRAINT PK_T_TEST PRIMARY KEY (ID);


/******************************************************************************/
/****                               Indices                               ****/
/******************************************************************************/
CREATE INDEX T_TEST_IDX1 ON T_TEST (NAME);
CREATE INDEX T_TEST_IDX2 ON T_TEST (KEY_VALUE);


/******************************************************************************/
/****                               Triggers                              ****/
/******************************************************************************/
SET TERM ^ ;


/******************************************************************************/
/****                         Triggers for tables                         ****/
/******************************************************************************/
/* Trigger: T_TEST_BI0 */
CREATE OR ALTER TRIGGER T_TEST_BI0 FOR T_TEST
ACTIVE BEFORE INSERT POSITION 0
AS
begin
  /* Trigger text */
  if (new.id is null) then
    new.id = GEN_ID(G_TEST, 1);
end
^

SET TERM ; ^
Die Tabelle habe ich mit 30.000 Testdatensätzen befüllt.

Wenn ich nun folgenden Abruf mache:

Code:
select
t.*
from t_test t
where
(
  (:test_name = cast('*' as varchar(201)))
  or
  ((not (:test_name = cast('*' as varchar(201)))) and (f_lrtrim8(f_upper(t.name)) = f_lrtrim(f_upper(:test_name))))
)
and
(
  (:test_value = cast('*' as varchar(201)))
  or
  ((not (:test_value = cast('*' as varchar(201)))) and (t.key_value = :test_value))
)
und dabei folgende Parmeterbelegung verwende:

Code:
TEST_NAME = '*' <- also nur das Zeichen als String
TEST_VALUE = 12
dann wird folgender Plan verwendet:
Code:
Plan:
PLAN (T NATURAL)
Der Index wird also nicht benutzt.

Ändere ich die Abfrage wie folgt:

Code:
select
t.*
from t_test t
where
t.name = f_lrtrim(f_upper(:test_name))
and
t.key_value = :test_value
wird bei gleicher Parameterbelegung dieser Plan verwendet:

Code:
Plan:
PLAN (T INDEX (T_TEST_IDX1, T_TEST_IDX2))
Jetzt wird der Index benutzt.

Warum wird bei der ersten Abfrage der Index nicht verwendet und wie kann ich das vermeiden?
Ich vermute, dass dies an der Parameterabfrage liegt.

Anmerkung:
dies ist ein vereinfachtes Beispiel aus einer komplexeren Konstellation heraus.
Es ist daher wirklich nicht einfach möglich, die Parameter zu vermeiden bzw. anders zu belegen ;-(.



Danke.
  Mit Zitat antworten Zitat