In an SQL Server database, I created a Unique Constraint to ensure that one of it's tables contains only unique pairs of values.
The problem now is that the order of records I get is different. The records are sorted, but I want them to come in original order, just as they exist in the table, without any sorting.
I've checked everywhere, but couldn't find a way to create a unique constraint without sort order. Is this supported at all?
The records are sorted, but I want them to come in original order, just as they exist in the table, without any
sorting.
Ah, the old sort issue - SQL for beginners.
TABLES have a sort order that is the order of the clustered index. Missing that the odder is undefined.
RESULTS have NO ORDER UNLESS DEFINED. SQL can change the order if it thinks it can process a query better. This is FUNDAMENTAL - you deal with data sets, and data sets per se are not ordered.
So, if you want an order, ASK FOR IT.
but couldn't find a way to create a unique constraint without sort order.
Why would you need an order for a unique constraint? A unique index should suffice, or? I would NOT make uniqueness a constraint but put - standard - a unique index on the fields. Especially as the index is good for - validating that they are unique and thus needed anyway.
IF you want to get your records in the "original" order - you should use any field which will mark this order, such as an identity sequence / primary key (probably the best option you can use), or a creation date or anything else.
The rows in ur table (physically, in the file) are actually sorted by a particular order only when you use a clustered index, however, even in that case, there are no guarantees whatsover that this or any order will be preserved when you selected rows from that table, without any order by clause.
Usually, with a clustered table, You'll get the results in the order of the clustered index, however this is not something you can rely on, and wherever order is important, you should provide ORDER BY in your query.
Using ROW_NUMBER you can get how your order is stored without using sort_order. I hope it help.
Related
I am recently working with Entity Framework Core and I have some issue about the relation between the primary key and the indexes.
To be more concrete, I found out that in a table containing composite primary keys an index is created for the second property of the key.
You can see an example here
Can you explain me if I should manually create another index for the first one? Or is a clustered index created for that first property?
Generally an index on a set of columns can be used even if a query is only searching some of the columns, with the restriction that the query must ask for columns from the index left to right, no gaps
Thus if a set of columns A,B,C,D are indexed, this index can still be used to answer queries that are filtering on A, A and B, A and B and C.
Thus you don't need to index NoteID separately, because the index that aids the primary key (NoteID, CategoryID) can be used by queries calling for just NoteID. It cannot, however, be used to answer queries calling for just CategoryID, hence the separate index being created
As an aside, you might find, in some cases, that you can supply values in a where clause that have no purpose other than to encourage use of an index that covers them. Suppose, for example, that a table has an index on Name, Gender, Age, and you want all 20 year old people named Steven. If you can reasonably assert that Steven is always male, you can WHERE Name = 'Steven' AND Gender = 'M' AND Age = 20 - even though the Gender of M is redundant, specifying it will let the DB engine use that index. Omitting it means the DB will have a much harder job of figuring out whether to use the index or not
You can also re-arrange index ordering to help your application perform, and give the DB fewer indexes to maintain.. If all your queries will only ever ask for A, A+C or A+B+C, it would be better to specify the index for the columns in the order A,C,B then a single index can cover all queries, rather than having to maintain an index of A+B+C and another of A+C
You don't need to create an index on NoteID because it is the first column of the primary key. Generally, you want all foreign keys to be the first column in at least one index. In your case, NoteID is the first column in the primary key which acts as a clustered unique index.
I want to add an object after the last row in table. But the object is randomly inserted anywhere in the table; sometimes at first, sometimes at middle; sometimes at last. I was sending an object from my frontend to web api.I generated the primary key by guid. It is GUID type. Before that it was string type. I am using code-first flow. Any help?
I generated the primary key by guid.
Records are always maintained in the backing data by the clustered index. If you want the inserts to generally append at the end of the clustered index, use an IDENTITY integer primary key instead. (For SQL Server that is. Other database engines can use different keywords to define an incrementing integer PK.)
Additionally, when querying the data there is never a guaranteed sort unless you explicitly provide one. Any time you query your data and want a specific ordering, use an ORDER BY clause. (.OrderBy() in LINQ application code.)
i want to store a great amount of strings into my sqlite database. I want them to be always in the same order when i read them as i add them to the database. I know i could give them an autoincrementing primary key and sort by that but since there can be up to 100.000 strings this is a performance issue. Besides the order should NEVER change or be sorted in any different way.
short example:
sql insert "hghtzdz12g"
sql insert "jut65bdt"
sql insert "lkk7676nbgt"
sql select * should give ALWAYS this order {"hghtzdz12g", "jut65bdt", "lkk7676nbgt" }
Any ideas how to achive this ?
Thanks
In a query like
SELECT * FROM MyTable ORDER BY MyColumn
the database does not need to sort the results if the column is indexed, because it can just scan through the index entries in order.
The rowid (or whatever you call the autoincrementing column) is an index, and is even more efficient than a separate index.
If you are sure you will never need anything but exactly this array in exactly this order, you can cheat the database and put in a single blob field.
But then you should ask yourself why you chose a database in the first place.
The correct database solution is indeed a table using a key that you can sort by.
If this performance is not enough, you can have a look here for performance hints.
If you need ultra-fast performance, maybe a database is not the best tool for the job. Databases are used for their ACID abilities and speed is not one of them but rather a secondary objective of everything in software.
The application I have completed has gone live and we are facing some very specific problems as far as response time is concerned in specific tables.
In short, response time in some of the tables that have 5k rows is very low. And these tables will grow in size.
Some of these tables (e.g. Order Header table) have a uniqueidentifier as the P.K. We figure that this may be the reason for the low response time.
On studying the situation we have decided the following options
Convert the index of the primary key in the table OrderHeader to a non-clustered one.
Use newsequentialid() as the default value for the PK instead of newid()
Convert the PK to a bigint
We feel that option number 2 is ideal since option number 3 will require big ticket changes.
But to implement that we need to move some of our processing in the insert stored procedures to triggers. This is because we need to trap the PK from the OrderHeader table and there is no way we can use
Select #OrderID = newsequentialid() within the insert stored procedure.
Whereas if we move the processing to a trigger we can use
select OrderID from inserted
Now for the questions?
Will converting the PK from newid() to newsequentialid() result in performance gain?
Will converting the index of the PK to a non-clustered one and retaining both uniqueidentifier as the data type for PK and newid() for generating the PK solve our problems?
If you faced a similar sort of situation please do let provide helpful advice
Thanks a tons in advance people
Romi
Convert the index of the primary key in the table OrderHeader to a non-clustered one.
Seems like a good option to do regardless of what you do. If your table is clustered using your pkey and the latter is a UUID, it means you're constantly writing somewhere in the middle of the table instead of appending new rows to the end of it. That alone will result in a performance hit.
Prefer to cluster your table using an index that's actually useful for sorting; ideally something on a date field, less ideally (but still very useful) a title/name, etc.
Move the clustered index off the GUID column and onto some other combination of columns (your most often run range search, for instance)
Please post your table structure and index definitions, and problem query(s)
Before you make any changes: you need to measure and determine where your actual bottleneck is.
One of the common reasons for a GUID Primary Key, is generating these ID's in a client layer, but you do not mention this.
Also, are your statistics up to date? Do you rebuild indexes regularly?
Using the ADO.NET MySQL Connector, what is a good way to fetch lots of records (1000+) by primary key?
I have a table with just a few small columns, and a VARCHAR(128) primary key. Currently it has about 100k entries, but this will become more in the future.
In the beginning, I thought I would use the SQL IN statement:
SELECT * FROM `table` WHERE `id` IN ('key1', 'key2', [...], 'key1000')
But with this the query could be come very long, and also I would have to manually escape quote characters in the keys etc.
Now I use a MySQL MEMORY table (tempid INT, id VARCHAR(128)) to first upload all the keys with prepared INSERT statements. Then I make a join to select all the existing keys, after which I clean up the mess in the memory table.
Is there a better way to do this?
Note: Ok maybe its not the best idea to have a string as primary key, but the question would be the same if the VARCHAR column would be a normal index.
Temporary table: So far it seems the solution is to put the data into a temporary table, and then JOIN, which is basically what I currently do (see above).
I've dealt with a similar situation in a Payroll system where the user needed to generate reports based on a selection of employees (eg. employees X,Y,Z... or employees that work in certain offices). I've built a filter window with all the employees and all the attributes that could be considered as a filter criteria, and had that window save selected employee id's in a filter table from the database. I did this because:
Generating SELECT queries with dynamically generated IN filter is just ugly and highly unpractical.
I could join that table in all my queries that needed to use the filter window.
Might not be the best solution out there but served, and still serves me very well.
If your primary keys follow some pattern, you can select where key like 'abc%'.
If you want to get out 1000 at a time, in some kind of sequence, you may want to have another int column in your data table with a clustered index. This would do the same job as your current memory table - allow you to select by int range.
What is the nature of the primary key? It is anything meaningful?
If you're concerned about performance I definitely wouldn't recommend an 'IN' clause. It's much better try do an INNER JOIN if you can.
You can either first insert all the values into a temporary table and join to that or do a sub-select. Best is to actually profile the changes and figure out what works best for you.
Why can't you consider using a Table valued parameter to push the keys in the form of a DataTable and fetch the matching records back?
Or
Simply you write a private method that can concatenate all the key codes from a provided collection and return a single string and pass that string to the query.
I think it may solve your problem.