different sequence same field in indexing are different - sql-server-2008

I have creat two indexes . The question is that [BCLIENT], [NAME] And in Second [NAME], [BCLIENT] Is that both will equal or it will work different manner , because i change the sequence in the indexing .
CREATE NONCLUSTERED INDEX [bclient] ON [dbo].[client]
(
[BCLIENT] ASC,
[NAME] ASC
)
GO
And Second index is Like this
CREATE NONCLUSTERED INDEX [RDATE] ON [dbo].[client]
(
[NAME] ASC,
[BCLIENT] ASC
)

No, they will not be equal, and will not act the same.
I always refer to the phone book example as a good reference for this.
Lets asy you have a query as follows
SELECT *
FROm PhoneBook
WHERE Surname = 'TADA'
and you have an index create as Surname, Name, the index would be properly used, but if the index was in the order Name, Surname the query engine would not be able to use the index, and would have to do an index scan/ table scan/ clustered index scan.

Related

MySql Indexes Sort and Where

I would like to know how MySql handle the indexes priority. I have the following table.
CREATE TABLE table (
colum1 VARCHAR(50),
colum2 VARCHAR(50),
colum3 ENUM('a', 'b', 'c'),
PRIMARY KEY(colum1, colum2, colum3)
);
CREATE INDEX colum1_idx ON table (colum1);
CREATE INDEX coloum2_idx ON table (colum2);
const query = `SELECT * FROM table
WHERE colum1 = ?
ORDER BY colum2
LIMIT ?,?`;
Basically my PK is composed by all fields (I need to use INSERT IGNORE) and I am query using colum1 as WHERE clause and ORDER by colum2.
My question is should I create 2 different indexes or create 1 index with (colum1 and colum2)?
Thanks to #JuanCarlosOpo
I find the answer here: http://mysql.rjweb.org/doc.php/index_cookbook_mysql#algorithm_step_2c_order_by_
It's more performant using a compound index using both columns.
CREATE INDEX colum_idx ON table (colum1,colum2);
Thanks a lot!

CONTAINS doesn't return any result

I know LIKE can be used instead of CONTAINS but CONTAINS is relatively faster as compared to LIKE. Here, the following query doesn't return me any result. Why?
Query:
SELECT CustomerName FROM members WHERE CONTAINS(Country, 'Mexico');
DATABASE:
MySQL Solution
select customername
from members
where match(country) against ('Mexico')
MS SQL Server Solution
Full text indexes aren't necessarily always populated after creation.
Use the following code to ensure the index updates:
ALTER FULLTEXT INDEX ON members SET CHANGE_TRACKING AUTO;
More info: https://msdn.microsoft.com/en-us/library/ms142575.aspx
Full example (including change tracking option on index creation rather than in a later alter statement):
use StackOverflow
go
create table myTable
(
id bigint not null identity(1,1)
constraint myTable_pk primary key clustered
, name nvarchar(100)
);
create fulltext catalog StackOverflow_Catalog;
create fulltext index
on myTable(name)
key index myTable_pk
on StackOverflow_Catalog
with change_tracking auto;
insert myTable
select 'Mexico'
union select 'London';
select *
from myTable
where contains(name,'Mexico');
Have you tried using in it might be even faster if it works in your case
SELECT CustomerName
FROM members
WHERE Country IN ('Mexico')
But in your case you may put %% in contains is actually faster then contain so just use this
SELECT CustomerName
FROM members
WHERE CONTAINS(Country, '"*Mexico"');
try this
If there is Full-Text Search Index on column Country.
SELECT CustomerName FROM members
WHERE CONTAINS(Country, 'Mexico');
Otherwise just do
SELECT CustomerName FROM members
WHERE Country LIKE N'%Mexico%';
there is a unicode character é, you need to prefix the string with N

What changes shall we make in the table

I was asked below question in an interview which i could not answer.Could anyone please help.
A primary school teacher wants to store the first name,last name,date of birth,gender(0=female and 1=male) and home phone number of each of her pupils in a MySQL database.She came up with the following table definition:
CREATE TABLE pupil(
pupil_id INT NOT NULL AUTO_INCREMENT,
first_name CHAR(50),
last_name CHAR(50),
date_of_birth CHAR(50),
gender INT,
phone_number CHAR(50),
PRIMARY_KEY (pupil_id)
)ENGINE=MyISAM DEFAULT CHARSET=utf8;
she frequently runs the following queries
select * from pupil where pupil_id = 2;
select * from pupil where first_name = 'John';
select * from pupil where first_name = 'John' and last_name = 'Doe';
What changes will you make to this table? and why?
My answer would have been I would add two indexes. One for first_name and one for first_name, last_name.
If you frequently query according to the first name or the first and last names, it might be a good idea to index them:
CREATE INDEX pupil_names_ind ON pupil (first_name, last_name);
Having said that, you should really run a benchmark first. If the table has just a couple of hundreds of rows most of them will be caches anyway, and indexing it would be a wasted effort.
You just want one index
CREATE INDEX pupils_by_name ON pupil (first_name, last_name)
first query(by id) is optimised thanks to primary key
second query(by first name) is handled by pupils_by_name index, because it fits the index column orders starting from left hand side, if you would want to optimise a query by 'last_name' field, this index would't work because the order of columns in where clause must match an order of columns in and index starting from the left
thrid query fits the index pupils_by_name perfectly
in addition
date_of_birth CHAR(50) should be date
gender INT should be tinyint
I would create indexes on the first_name and last_name (in that order). it is important. more info here : http://dev.mysql.com/doc/refman/5.0/en/mysql-indexes.html
Then i would change the date_of_birth datatype to date
You should add an index in the table in the columns first_name and last_name.
Syntax : CREATE INDEX `ind` ON `table`(`col`);
This will make the searches on the indexed columns fast. Go through this article => When to use indexes? and MySQL's docs. Basically you use indexes on frequently searched items to boost the performance. But remember one thing : Too many indexes slow insertions into the table. So, an effective usage of indexes will definitely speed up a query.

"order by" kills performance

I'm not a MySQL guy, actually I'm doing this to help a friend.
I have these tables in a MySQL database:
create table post (ID bigint, p text)
create table user (ID bigint, user_id bigint)
and I'm querying them by this script:
select * from post
where ID in (select user_id from user where ID = 50)
order by ID DESC --this line kills performance.
limit 0,20
As I mentioned in comment, when there is no order by ID DESC, the query executes very fast. But when I add that to the query, it got very very slow with a huge CPU usage. Do you have any idea what am I doing wrong?
You should define ID as Primary Key for your table. This will add an index and increase performance. At least as a first step, it's a good one.
This query should do the trick:
create table post (
ID bigint,
p text,
PRIMARY KEY (ID));
Thanks to #frlan the problem got solved by indexes:
CREATE INDEX IDX_POST_ID ON post (ID);
CREATE INDEX IDX_USER_ID ON user (ID);
CREATE INDEX IDX_USER_USERID ON user (user_id);

Search by primary key and then sort

I'm using MySQL and I have a database that I'm trying to use as the canonical version of data that I will be storing in different indexes. That means that I have to be able to retrieve a set of data quickly from it by primary key, but I also need to sort it on the way out. I can't figure out how to let MySQL efficiently do that.
My table looks like the following:
CREATE TABLE demo.widgets (
id INT AUTO_INCREMENT,
-- lots more information I need
awesomeness INT,
PRIMARY KEY (id),
INDEX IDX_AWESOMENESS (awesomeness),
INDEX IDX_ID_AWESOMENESS (id, awesomeness)
);
And I want to do something along the lines of:
SELECT *
FROM demo.widgets
WHERE id IN (
1,
2,
3,
5,
8,
13 -- you get the idea
)
ORDER BY awesomeness
LIMIT 50;
But unfortunately I can't seem to get good performance out of this. It always has to resort to a filesort. Is there a way to get better performance from this setup, or do I need to consider a different database?
This is explained in the documentation ORDER BY Optimization. In particular, if the index used to select rows in the WHERE clause is different from the one used in ORDER BY, it won't be able to use an index for ORDER BY.
In order to get an optimized query to fetch and retrieve like that, you need to have a key that orders by sort and then primary like so:
create table if not exists test.fetch_sort (
id int primary key,
val int,
key val_id (val, id)
);
insert into test.fetch_sort
values (1, 10), (2, 5), (3, 30);
explain
select *
from test.fetch_sort
where id in (1, 2, 3)
order by val;
This will give a query that only uses the index for searching/sorting.