Mysql - Entity Framework performance issue on "order by" / Subquery - c#

I have one table that stores 3k records,
I'm new with Entity Framework and ORMs but i can understand that something going wrong.
When i run this linq query :
repo.GetQuery<Article>().Where(foo=>foo.Expires_date>=date
&& foo.Istoparticle==true
&& foo.Isfrontpage==false)
.OrderByDescending(foo=>foo.Date)
.Take(4);
I get this query on mysql side :
SELECT
`Project1`.`Id`,
`Project1`.`User_id`,
`Project1`.`Category_id`,
`Project1`.`Title`,
`Project1`.`Value`,
`Project1`.`Keywords`,
`Project1`.`Description`,
`Project1`.`Images`,
`Project1`.`Votes`,
`Project1`.`Views`,
`Project1`.`Isvisible`,
`Project1`.`Isfrontpage`,
`Project1`.`Istoparticle`,
`Project1`.`Date`,
`Project1`.`Expires_date`,
`Project1`.`Votes_sum`
FROM (SELECT
`Extent1`.`Id`,
`Extent1`.`User_id`,
`Extent1`.`Category_id`,
`Extent1`.`Title`,
`Extent1`.`Value`,
`Extent1`.`Keywords`,
`Extent1`.`Description`,
`Extent1`.`Images`,
`Extent1`.`Votes`,
`Extent1`.`Votes_sum`,
`Extent1`.`Views`,
`Extent1`.`Isvisible`,
`Extent1`.`Isfrontpage`,
`Extent1`.`Istoparticle`,
`Extent1`.`Expires_date`,
`Extent1`.`Date`
FROM `tcms_articles` AS `Extent1`
WHERE `Extent1`.`Expires_date` >= '2012-06-24 13:41:47.816') AS `Project1`
ORDER BY
`Project1`.`Date` DESC LIMIT 4
It takes about 3.50 sec to exequte this query.
Explain of this query :
+----+-------------+------------+-------+---------------+--------------+---------+------+------+----------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------+-------+---------------+--------------+---------+------+------+----------------+
| 1 | PRIMARY | | ALL | NULL | NULL | NULL | NULL | 4054 | Using filesort |
| 2 | DERIVED | Extent1 | range | expires_date | expires_date | 8 | NULL | 4053 | Using where |
+----+-------------+------------+-------+---------------+--------------+---------+------+------+----------------+
When i query :
SELECT *
FROM tcms_articles
WHERE expires_date >= '2012-06-24 13:41:47.816'
ORDER BY date DESC
limit 4
I get 0.01 sec...
Running explain again i get :
+----+-------------+---------------+-------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------------+-------+---------------+------+---------+------+------+-------------+
| 1 | SIMPLE | tcms_articles | index | expires_date | date | 8 | NULL | 11 | Using where |
+----+-------------+---------------+-------+---------------+------+---------+------+------+-------------+
I don't understand why this is happening.
Entity Framework 4.3
MySQL Connector Net 6.5.4.0
EDIT :
The tcms_articles :
CREATE TABLE `tcms_articles` (
`Id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`User_id` int(10) unsigned DEFAULT NULL,
`Category_id` int(10) unsigned DEFAULT NULL,
`Title` varchar(255) DEFAULT NULL,
`Value` longtext,
`Keywords` varchar(255) NOT NULL DEFAULT '',
`Description` varchar(255) NOT NULL DEFAULT '',
`Images` longtext NOT NULL,
`Votes` int(10) unsigned NOT NULL DEFAULT '1',
`Votes_sum` int(10) unsigned NOT NULL DEFAULT '5',
`Views` int(10) unsigned NOT NULL DEFAULT '0',
`Isvisible` tinyint(1) unsigned NOT NULL DEFAULT '1',
`Isfrontpage` tinyint(1) unsigned NOT NULL DEFAULT '0',
`Istoparticle` tinyint(1) unsigned NOT NULL DEFAULT '1',
`Expires_date` datetime NOT NULL DEFAULT '2099-12-31 00:00:00',
`Date` datetime NOT NULL,
PRIMARY KEY (`Id`),
KEY `article_users` (`User_id`) USING BTREE,
KEY `article_section` (`Category_id`) USING BTREE,
KEY `Isvisible_index2` (`Isvisible`) USING BTREE,
KEY `Istoparticle_index2` (`Istoparticle`) USING BTREE,
KEY `Expires_date_index2` (`Expires_date`) USING BTREE,
KEY `isfrontpage2` (`Isfrontpage`) USING BTREE,
KEY `Date_index2` (`Date`) USING BTREE,
CONSTRAINT `tcms_articles_ibfk_1` FOREIGN KEY (`Category_id`) REFERENCES `tcms_categories` (`Id`)
ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `tcms_articles_ibfk_2` FOREIGN KEY (`User_id`) REFERENCES `tcms_users` (`Id`)
ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=80 DEFAULT CHARSET=utf8;
So why Linq produces this query and how/can i fix this?

repo.GetQuery<Article>().Where(foo=>foo.Expires_date>=date -- Note 1
&& foo.Istoparticle==true
&& foo.Isfrontpage==false)
.OrderByDescending(foo=>foo.Date) -- Note 2
.Take(4);
Use foo.Expires_date in both places.

Related

Cassandra Update - 'Where' with timestamp clustering key

I have a table in cassandra with following structure:
CREATE TABLE answers (
Id uuid,
Name text,
Description text,
LastVersion boolean,
CreationDate timestamp,
EditionDate timestamp,
PRIMARY KEY(Id, EditionDate)
)WITH CLUSTERING ORDER BY (EditionDate DESC);
The problem is when I need to update the value of the LastVersion column to false. In this case a new line is inserted only with the values ​​of the Primary Key (Id, EditionDate) + the value of the LastVersion column.
In this order:
INSERT:
insert into answers
(id, name, description, lastversion, creationdate, editiondate)
values
(uuid(), 'Test 1', 'Description 1', true, dateof(now()), dateof(now()));
RESULT:
id | editiondate | creationdate | description | lastversion | name
--------------------------------------+---------------------------------+---------------------------------+---------------+-------------+--------
ac4f9ec1-8737-427c-8a63-7bdb62c93932 | 2018-08-01 19:54:51.603000+0000 | 2018-08-01 19:54:51.603000+0000 | Description 1 | True | Test 1
UPDATE:
update answers
set lastversion = false
where id = ac4f9ec1-8737-427c-8a63-7bdb62c93932
and editiondate = '2018-08-01 19:54:51';
RESULT:
id | editiondate | creationdate | description | lastversion | name
--------------------------------------+---------------------------------+---------------------------------+---------------+-------------+--------
ac4f9ec1-8737-427c-8a63-7bdb62c93932 | 2018-08-01 19:54:51.603000+0000 | 2018-08-01 19:54:51.603000+0000 | Description 1 | True | Test 1
ac4f9ec1-8737-427c-8a63-7bdb62c93932 | 2018-08-01 19:54:51.000000+0000 | null | null | False | null
What is wrong? Actually the EditionTime field seems to be different but, I spend the same value on UPDATE query.
your update is using a different value for editionDate than you inserted so your update is not finding the original row. And Cassandra updates and inserts are really upserts so a new row with the new key is being inserted.
Notice the EditionDate has millisecond precision but your update is only specifying it to the nearest second.

Auto increment a column value based on another column of a database table

I am creating a university course and results management system on c# .net. I have created this table on database.
CREATE TABLE Students (
[ID] [int] IDENTITY (1, 1) NOT NULL PRIMARY KEY,
[RegistrationNo] AS ([Department] + '-' + CAST(YEAR([Date]) AS char(4)) + '-' + RIGHT('00' + CONVERT(varchar(3), ID), 3)),
[Name] [varchar](40) NOT NULL,
[Email] [varchar](50) NOT NULL,
[Department] [varchar](20) NOT NULL,
[Date] [date] NOT NULL
)
Values are:
ID | RegistrationNo | Name | Email | Department | Date
1 | CSE-2018-001 | Robiul | robiul#mail.com | CSE | 2018-05-05
2 | CSE-2018-002 | Arman | arman#mail.com | CSE | 2018-05-10
3 | EEE-2018-003 | Sayed | sayed#mail.com | EEE | 2018-06-10
4 | EEE-2017-004 | Sazzad | sazzad#mail.com | EEE | 2017-06-10
User only gives the Name,Email,Department and Date. ID and RegistrationNo is auto generateing.
But I want to increment the RegistrationNo based on Department and Year of Date. For example CSE-2017's first ID's RegistrationNo will like this 'CSE-2017-001' and the next will 'CSE-2017-002'. EEE-2018-003 will be 'EEE-2018-001'

Creating a constraint on two columns to support specific rule

I have a table storing Device details. For simplicity, the columns are:
Id (Primary Key)
Name (varchar)
StatusId (Foreign Key to Status table).
The Status table has two columns:
Id (Primary Key)
State (varchar)
and two rows:
[Id | State]
1 | Active
2 | Inactive
I would like to allow multiple devices in the Devices table with the same Name, but only one of them can have status Active at any time.
That is to say, this should be allowed in the Devices table:
[Id | Name | StatusId]
10 | Mobile001 | 1
11 | Mobile001 | 2
12 | Mobile001 | 2
20 | Tablet001 | 1
21 | Tablet002 | 2
22 | Tablet002 | 1
23 | Tablet003 | 2
But this should not be allowed:
[Id | Name | StatusId]
10 | Mobile001 | 1 <-- wrong
11 | Mobile001 | 1 <-- wrong
12 | Mobile001 | 2
20 | Tablet001 | 1
21 | Tablet002 | 1 <-- wrong
22 | Tablet002 | 1 <-- wrong
23 | Tablet003 | 2
Is there a way how to create a constraint in T-SQL to reject inserts and updates that violate this rule? And is there a way how to do it in EF code first using EntityTypeConfigurations and Fluent API, possibly via IndexAnnotation or IndexAttributes?
Thanks.
One method, as #ZoharPeled just commented is using a filtered unique index.
As you are only allowed one Active Device of a specific name, this can be implemented as below:
USE Sandbox;
GO
--Create sample table
CREATE TABLE Device (ID int IDENTITY(1,1),
[name] varchar(10),
[StatusID] int);
--Unique Filtered Index
CREATE UNIQUE INDEX ActiveDevice ON Device ([name], [StatusID]) WHERE StatusID = 1;
GO
INSERT INTO Device ([name], StatusID)
VALUES ('Mobile1', 1); --Works
GO
INSERT INTO Device ([name], StatusID)
VALUES ('Mobile1', 0); --Works
GO
INSERT INTO Device ([name], StatusID)
VALUES ('Mobile2', 1); --Works
GO
INSERT INTO Device ([name], StatusID)
VALUES ('Mobile1', 1); --Fails
GO
UPDATE Device
SET StatusID = 1
WHERE ID = 2; --Also fails
GO
SELECT *
FROM Device;
GO
DROP TABLE Device;
Any questions, please do ask.
In EF CF You could achieve it by setting an unique index like described in this answer.
modelBuilder.Entity<Device>()
.HasIndex(d => new { d.Name, d.StatusId })
.IsUnique();

ORACLE: Use static value when defining foreign key constraint

How can I define a foreign key constraint like this in ORACLE:
ALTER TABLE TEST_STORES ADD CONSTRAINT FK_STORE_TYPE
FOREIGN KEY ("StoreTable", STORE_TYPE) REFERENCES TEST_ENUMERATIONS (TABLE, VALUE)
/
I want to combine all Enum values of several tables in one table.
In order to create a foreign key I need also to check the type of the enum since the value alone is not unique.
I need it like this so I can define the Store_Type as enum (C#) in my program but at the same time I want to make sure the database values are all valid.
For example:
TEST_STORE table:
| ID | ... | STORE_TYPE
|-----------|------------|------------
| 324234 | | 0
| 324235 | | 0
| 324236 | | 1
TEST_ENUMERATIONS table:
| ID | TABLE | VALUE | NAME
|-----------|--------------|------------|-------------
| 567234 | StoreTable | 0 | NormalStore
| 567235 | StoreTable | 1 | SpecialStore
| 567236 | AnotherTable | 0 | AnotherType
Try creating a virtual column on TEST_STORES whose value is always 'StoreTable', and use the virtual column as the first column in the foreign key.
ALTER TABLE TEST_STORES ADD (ENUM_TABLE AS 'StoreTable');
ALTER TABLE TEST_STORES ADD CONSTRAINT FK_STORE_TYPE
FOREIGN KEY (ENUM_TABLE, STORE_TYPE) REFERENCES TEST_ENUMERATIONS (TABLE, VALUE)
Seems that you need:
ALTER TABLE TEST_STORES ADD CONSTRAINT FK_STORE_TYPE
FOREIGN KEY (NAME, STORE_TYPE) REFERENCES TEST_ENUMERATIONS (TABLE, VALUE)
/
You will need a unique key on test_enumerations(table,value) as well.

How do I find the shortest bus route when there is more than 1 switch? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I am developing a project which helps a person to find out the bus route with bus no and details of switches between the buses. I am able to find the route till single switch but more then that I am not able to do so. please help.
Now my quest is how to GO "SARAI" from "Cantt"? Using the same table.
Column Bus_Stop_Up is having the bus route in upwards and Bus_Stop_Down is having the bus route Downwards.
Result should be like "Cantt(781)->Dwarka(764)->Nehruplace(456)->SARAI"
Details of table are mention below:
CREATE TABLE [dbo].[bustable]
(
[Sr] [int] NULL
[bus_no] [varchar](50) NULL,
[Bus_Stop_Up] [varchar](50) NULL,
[Bus_Stop_Up_Id] [int] NULL,
[Bus_Stop_Down] [varchar](50) NULL,
[Bus_Stop_Down_Id] [int] NULL,
)
Table data
||Sr | bus_no | Bus_Stop_Up | Bus_Stop_Down | Bus_Stop_Up_Id | Bus_Stop_Down_Id||
-------------------------------------------------------------------------------------------------------------
||1 | 781 | DWARKA | NEW DELHI | 1 | 1 ||
||2 | 781 | Airport | Cantt | 2 | 2 ||
||3 | 781 | Cantt | Airport | 3 | 3 ||
||4 | 781 | NEW DELHI | DWARKA | 4 | 4 ||
||5 | 764 | DWARKA | NEHRU PLACE | 1 | 1 ||
||6 | 764 | NEHRUPLACE | DWARKA | 2 | 2 ||
||7 | 456 | NEHRU PLACE | SARAI | 1 | 1 ||
||8 | 456 | SARAI | NEHRU PLACE | 2 | 2 ||
I have posted such a thing a little while ago, here:
Graph problems: connect by NOCYCLE prior replacement in SQL server?
You'll find further going tips here, where i cross-posted the question:
http://social.msdn.microsoft.com/Forums/sqlserver/en-US/32069da7-4820-490a-a8b7-09900ea1de69/is-there-a-nocycle-prior-replacement-in-sql-server?forum=transactsql
CREATE TABLE [dbo].[T_Hops](
[UID] [uniqueidentifier] NULL,
[From] [nvarchar](1000) NULL,
[To] [nvarchar](1000) NULL,
[Distance] [decimal](18, 5) NULL
) ON [PRIMARY]
GO
INSERT INTO [dbo].[T_Hops] ([UID] ,[From] ,[To] ,[Distance]) VALUES (newid() ,'A' ,'E' ,10.00000 );
INSERT INTO [dbo].[T_Hops] ([UID] ,[From] ,[To] ,[Distance]) VALUES (newid() ,'E' ,'D' ,20.00000 );
INSERT INTO [dbo].[T_Hops] ([UID] ,[From] ,[To] ,[Distance]) VALUES (newid() ,'A' ,'B' ,5.00000 );
INSERT INTO [dbo].[T_Hops] ([UID] ,[From] ,[To] ,[Distance]) VALUES (newid() ,'B' ,'C' ,10.00000 );
INSERT INTO [dbo].[T_Hops] ([UID] ,[From] ,[To] ,[Distance]) VALUES (newid() ,'C' ,'D' ,5.00000 );
INSERT INTO [dbo].[T_Hops] ([UID] ,[From] ,[To] ,[Distance]) VALUES (newid() ,'A' ,'F' ,2.00000 );
INSERT INTO [dbo].[T_Hops] ([UID] ,[From] ,[To] ,[Distance]) VALUES (newid() ,'F' ,'G' ,6.00000 );
INSERT INTO [dbo].[T_Hops] ([UID] ,[From] ,[To] ,[Distance]) VALUES (newid() ,'G' ,'H' ,3.00000 );
INSERT INTO [dbo].[T_Hops] ([UID] ,[From] ,[To] ,[Distance]) VALUES (newid() ,'H' ,'D' ,1.00000 );
Now I can query the best connection from point x to point y like this:
WITH AllRoutes
(
[UID]
,[FROM]
,[To]
,[Distance]
,[Path]
,[Hops]
)
AS
(
SELECT
[UID]
,[FROM]
,[To]
,[Distance]
,CAST(([dbo].[T_Hops].[FROM] + [dbo].[T_Hops].[To]) AS varchar(MAX)) AS [Path]
,1 AS [Hops]
FROM [dbo].[T_Hops]
WHERE [FROM] = 'A'
UNION ALL
SELECT
[dbo].[T_Hops].[UID]
--,[dbo].[T_Hops].[FROM]
,Parent.[FROM]
,[dbo].[T_Hops].[To]
,CAST((Parent.[Distance] + [dbo].[T_Hops].[Distance]) AS [decimal](18, 5)) AS distance
,CAST((Parent.[Path] + '/' + [dbo].[T_Hops].[FROM] + [dbo].[T_Hops].[To]) AS varchar(MAX)) AS [Path]
,(Parent.[Hops] + 1) AS [Hops]
FROM [dbo].[T_Hops]
INNER JOIN AllRoutes AS Parent
ON Parent.[To] = [dbo].[T_Hops].[FROM]
)
SELECT TOP 100 PERCENT * FROM AllRoutes
/*
WHERE [FROM] = 'A'
AND [To] = 'D'
AND CHARINDEX('F', [Path]) != 0 -- via F
ORDER BY Hops, Distance ASC
*/
GO

Categories

Resources