Add an index to improve performance of this query? - firebird

Using: Firebird 2.52
For performance of SELECT for the following query, do I require indexes on additional fields in my table:
Desired query:
select inventory_id, max(batch_no) from invty_batch
where inventory_id = :I
group by inventory_id
Table structure:
CREATE TABLE INVTY_BATCH (
ROW_ID INTEGER NOT NULL,
INVENTORY_ID INTEGER NOT NULL,
BATCH_NO VARCHAR(8) NOT NULL,
INVTYRCPT_ID INTEGER NOT NULL,
UNITPRICE NUMERIC(12, 2) DEFAULT 0.0 NOT NULL);
ALTER TABLE INVTY_BATCH ADD PRIMARY KEY (ROW_ID);
CREATE UNIQUE INDEX IXINVTYIDBATCHNO ON INVTY_BATCH(INVENTORY_ID,BATCH_NO);
Will creating indexes on inventory_id and batch_no columns benefit performance for the given query?

try to create an index for the field "batch_no", because the query is doing a search in this field.
PS : Use a desc index, because the search is for the max value

Related

Postgresql not choosing rows grouping

I have query. There is a construction like this example: (online demo)
You will see the in result created_at field. I have to use query the created_at field. So I have to use it in select created_at. I don't want to use it created_at field in select. Because, there are millions of records in the deposits table. How can i escape this problem?
(Note: I have many table to query, like "deposits" table. this is just a short example.)
create table payment_methods
(
payment_method_id bigserial not null
constraint payment_methods_pkey
primary key
);
create table currencies_of_payment_methods
(
copm_id bigserial not null
constraint currencies_of_payment_methods_pkey
primary key,
payment_method_id integer not null
);
create table deposits
(
deposit_id bigserial not null
constraint deposits_pkey
primary key,
amount numeric(18,2) not null,
copm_id integer not null,
created_at timestamp(0)
);
INSERT INTO payment_methods (payment_method_id) VALUES (1);
INSERT INTO payment_methods (payment_method_id) VALUES (2);
INSERT INTO currencies_of_payment_methods (copm_id, payment_method_id) VALUES (1, 1);
INSERT INTO deposits (amount, copm_id, created_at) VALUES (100, 1, '2020-09-10 08:49:37');
INSERT INTO deposits (amount, copm_id, created_at) VALUES (200, 1, '2020-09-10 08:49:37');
INSERT INTO deposits (amount, copm_id, created_at) VALUES (40, 1, '2020-09-10 08:49:37');
Query:
SELECT payment_methods.payment_method_id,
deposit_copm_id.deposit_copm_id,
manuel_deposit_amount.manuel_deposit_amount,
manuel_deposit_amount.created_at
FROM payment_methods
CROSS JOIN lateral
(
SELECT currencies_of_payment_methods.copm_id AS deposit_copm_id
FROM currencies_of_payment_methods
WHERE currencies_of_payment_methods.payment_method_id = payment_methods.payment_method_id) deposit_copm_id
CROSS JOIN lateral
(
SELECT sum(deposits.amount) AS manuel_deposit_amount,
array_agg(deposits.created_at) AS created_at
FROM deposits
WHERE deposits.copm_id = deposit_copm_id.deposit_copm_id) manuel_deposit_amount
WHERE payment_methods.payment_method_id = 1

index on composite primary key columns

I have table called
CREATE TABLE process (
batch_id Integer
,product_id Integer
,machine_id Integer
,created_date DATE
,updated_date DATE
,primary key(batch_id,product_id,machine_id)
)
But I generally use SQL like
SELECT *
FROM process
WHERE product_id = 123
AND machine_id = 1
When i check SQL plan for this id does not uses primary key index.
Do i need to create another index of both columns?
Database is DB2

PostgreSQL query does not use index

Table definition is as follows:
CREATE TABLE public.the_table
(
id integer NOT NULL DEFAULT nextval('the_table_id_seq'::regclass),
report_timestamp timestamp without time zone NOT NULL,
value_id integer NOT NULL,
text_value character varying(255),
numeric_value double precision,
bool_value boolean,
dt_value timestamp with time zone,
exported boolean NOT NULL DEFAULT false,
CONSTRAINT the_table_fkey_valdef FOREIGN KEY (value_id)
REFERENCES public.value_defs (value_id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE RESTRICT
)
WITH (
OIDS=FALSE
);
ALTER TABLE public.the_table
OWNER TO postgres;
Indices:
CREATE INDEX the_table_idx_id ON public.the_table USING brin (id);
CREATE INDEX the_table_idx_timestamp ON public.the_table USING btree (report_timestamp);
CREATE INDEX the_table_idx_tsvid ON public.the_table USING brin (report_timestamp, value_id);
CREATE INDEX the_table_idx_valueid ON public.the_table USING btree (value_id);
The query is:
SELECT * FROM the_table r WHERE r.value_id = 1064 ORDER BY r.report_timestamp desc LIMIT 1;
While running the query PostgreSQL does not use the_table_idx_valueid index.
Why?
If anything, this index will help:
CREATE INDEX ON the_table (value_id, report_timestamp);
Depending on the selectivity of the condition and the number of rows in the table, PostgreSQL may correctly deduce that a sequential scan and a sort is faster than an index scan.

Postgres unique date column

I wanted to create table with unique date column. Is it possible?
I have following table:
CREATE TABLE senders (
id bigint NOT NULL,
number bigint NOT NULL,
inserted_at date NOT NULL
);
I want to be sure I will have unique values per date. For example I can insert (1, 1, '2017-01-01'),(1, 1, '2017-01-02') but I can't add then (1, 1, '2017-01-01') one more time. I tried using UNIQUE constraints creating table or unique indexes but always I have SQL unique exception.
CREATE UNIQUE INDEX senders_unique ON senders (id, number, inserted_at);
CREATE TABLE senders (
id bigint NOT NULL,
number bigint NOT NULL,
inserted_at date NOT NULL,
UNIQUE(id, number, inserted_at)
);
Is it possible. Thanks for all answers.

Getting a query to index seek (rather than scan)

Running the following query (SQL Server 2000) the execution plan shows that it used an index seek and Profiler shows it's doing 71 reads with a duration of 0.
select top 1 id from table where name = '0010000546163' order by id desc
Contrast that with the following with uses an index scan with 8500 reads and a duration of about a second.
declare #p varchar(20)
select #p = '0010000546163'
select top 1 id from table where name = #p order by id desc
Why is the execution plan different? Is there a way to change the second method to seek?
thanks
EDIT
Table looks like
CREATE TABLE [table] (
[Id] [int] IDENTITY (1, 1) NOT NULL ,
[Name] [varchar] (13) COLLATE Latin1_General_CI_AS NOT NULL)
Id is primary clustered key
There is a non-unique index on Name and a unique composite index on id/name
There are other columns - left them out for brevity
Now you've added the schema, please try this. SQL Server treats length differences as different data types and will convert the varchar(13) column to match the varchar(20) variable
declare #p varchar(13)
If not, what about collation coercien? Is the DB or server different to the column?
declare #p varchar(13) COLLATE Latin1_General_CI_AS NOT NULL
If not, add this before and post results
SET SHOWPLAN_TEXT ON
GO
If the name column is NVARCHAR then u need your parameter to be also of the same type. It should then pick it up by index seek.
declare #p nvarchar(20)
select #p = N'0010000546163'
select top 1 id from table where name = #p order by id desc