I have a CHAR(250) column being used as a foreign key to a varchar(24) column.
In MySQL I recall that I could create an index specifying column(24) in order to create an index on the leftmost 24 characters. This doesn't appear to be possible on MS SQL Server.
My question is this:
Is it possible to use an indexed view on SQL Server 2008 to index a substring of that column, and if so, would it have any side-effects on the table's performance?
You can create a persisted computed column, then index it, see Creating Indexes on Computed Columns
alter table add newcolumn as cast(oldcolumn as varchar(24)) persisted;
create index table_newcolumn on table (newcolumn);
I hope you have a good relational reason for doing this. I'm guessing the first 24 characters of the vendor-provided table actually constitute a discrete attribute and should have been in a separate column in the first place.
So...
Create a view of the vendor's table. Index it if you like. I doubt you can point a FK constraint at the view, but you certainly can write a trigger to the same effect. A trigger checking against an indexed view will be very fast, at the cost of a slight increase in update times on the view's base table.
HTH.
Related
Having the following schema:
CREATE TABLE test_table(
cryptid varchar(255)
);
CREATE INDEX cryptid_index ON test_table (cryptid);
I am trying to a unique contraint to the column.
ALTER TABLE test_table ADD constraint crypid_unique_contraint UNIQUE(cryptid);
But this runs into an error:
Could not execute 'ALTER TABLE test_table ADD constraint crypid_unique_contraint ...'
Error: (dberror) [261]: invalid index name: column list already indexed
I can understand that the column is already indexed because I have created the index by myself. But I want the column to be unique. Is there a way to do this?
This is indeed an undocumented limitation in the current HANA versions.
The only way to create a unique constraint on this column is to first drop the single-column index present on this column.
I would consider the fact that this is not documented a (docu-)bug. However, the fact that existing indexes cannot be generally reused for uniqueness checks is not.
Single-column indexes in HANA's column store (which is what you use by default) tables are not B-tree indexes. Instead, these are inverted indexes into the column store structure of the main store-part of a column store table column.
These inverted structures cannot be checked for duplicates in the current transactional context as easily as B-tree indexes could.
This, I believe, is the reason for
a) implementing the uniqueness check only on a specific index implementation in the column store,
and
b) making the system behavior (not allowing the "conversion" of an existing index into a unique index) consistent across all table types.
As a general comment: for column store tables the benefit of single-column indexes for lookup/point-read scenarios is very often not worth the additional storage & compute resource consumption. This type of index practically doubles the memory requirement for the indexed column. So the speed-up in looking up a specific value should be worthwhile this additional permanent resource consumption.
You may check the documentation on INDEXES system view. They listed this index types:
Type of row store indexes: BTREE, BTREE_UNIQUE, CPBTREE, and CPBTREE_UNIQUE.
"Simple" index and unique index are a different index types at a build time, so there's no way to change it after the index was declared.
In other databases when you add unique constraint, it creates a new unique index (like in T-SQL or MySQL or Postgers) or reuses current index with this column (as in Oracle). But HANA doesn't allow you to create ether additional index on the same column (due to unknown reason, I didn't find it documented) or enforce constraint using existing index (due to poor implementation of mixture of uniqueness and index type).
The only way to go is to drop existing index and create it as unique (it is equivalent to unique constraint from the metadata point of view) from scratch, which you cannot due to authorizations. Sad but...
Please suppose you have a table called BEER_HERE, with two columns:
BEER_CODE VARCHAR(50)
BEER_DATE DATETIME
Please suppose also you have the availability of a function called dbo.TRUNCATE_DATE which works as follows:
dbo.TRUNCATE_DATE ('23/12/2012 23:59:57.395') ==> 23/12/2012 00:00:00.000
I would like to create a FUNCTION BASED INDEX on:
(BEER_CODE, dbo.TRUNCATE_DATE(BEER_DATE))
How could I achieve this?
Thank you in advance for your kind help.
You would need to add a computed column
Alter Table BEER_HERE Add Column XBEER_DATE As dbo.TRUNCATE_DATE(BEER_DATE)
You can then index it as you'd expect.
However, your function needs to be deterministic and precise as defined in http://msdn.microsoft.com/en-us/library/ms189292(v=sql.90).aspx. Your function should meet these requirements, but you might need to add With SchemaBinding to the function definition.
You might also be able to use a view
Create View V_BEER_HERE As Select BEER_CODE, BEER_DATE, dbo.TRUNCATE_DATE(BEER_DATE) As XBEER_DATE From BEER_HERE
Create Unique Clustered Index PK_V_BEER_HERE On V_BEER_HERE (BEER_CODE)
Create Index I_XBEER_DATE On V_BEER_HERE (XBEER_DATE)
Stuff that inserts writes to the table, stuff that reads reads from the view. This depends on BEER_CODE being a primary key.
SQL Server doesn't have function based indexes the same way Oracle does.
I'm having a rather silly problem. I'll simplify the situation: I have a table in SQL Server 2008 R2 where I have a field 'ID' (int, PK) and a Name (nvarchar(50)) and Description (text) field. The values in the Name - field should be Unique. When searching the table, the Name - field will be used so performance is key here.
I have been looking for 2 hours on the internet to completely understand the differences between Unique Key, Primary Key, Unique Index and so on, but it doesn't help me solve my problem about what key/constraint/index I should use.
I'm altering the tables in SQL Server Management Studio. My question for altering that Name - field is: should I use "Type = Index" with "Is Unique = Yes" or use "Type = Unique Key"?
Thanks in advance!
Kind regards,
Abbas
A unique key and a primary key are both logical constraints. They are both backed up by a unique index. Columns that participate in a primary key are not allowed to be NULL-able.
From the point of view of creating a Foreign Key the unique index is what is important so all three options will work.
Constraint based indexes have additional metadata stored that regular indexes don't (e.g. create_date in sys.objects). Creating a non constraint based unique index can allow greater flexibility in that it allows you to define included columns in the index definition for example (I think there might be a few other things also).
A unique key cannot have the same value as any other row of a column in a table. A primary key is the column field(s) that is a unique key and not null which is used as the main look up mechanism (meaning every table should have a primary key as either a column or combination of columns that represent a unique entry).
I haven't really used indexes much, but I believe it follows the same logic.
See http://en.wikipedia.org/wiki/Unique_key for more information.
An index is a collection the DBMS uses to organize your table data efficiently. Usually you want to create an index on columns and groups of columns that you frequently search on. For example, if you have a column 'name' and you are searching your table where name = '?' and index on that column will create separate storage that orders that table so searching for a record by name is fast. Typically primary keys are automatically indexed.
Of course the above is a bit too general and you should consider profiling queries before and after adding an index to ensure it's being used and speeding things up. There are quiet a few subtleties to indexes that make the application specific. They take extra storage and time to build and maintain so you always want to be judicious about adding them.
Hope this helps.
How to create a unique constraint on a varchar(max) field in visual studio, visually.
the problem is when i try it:
manage indexes and keys > add > columns
I can only chose the bigint columns, but not any of the varchar(max) ones.
Do I maybe have to use check constraints?
If yes, what to put in the expression?
Thnx for the info
You cannot put a unique constraint on a VARCHAR(MAX) column (which could be up to 2 GB of text!!). You just simply cannot.
The unique constraint is enforced by a unique index in the background, and SQL Server has a 900 byte limit on index entries. You also cannot put a unique constraint on a VARCHAR(2000) field for that reason.
You'll need to find another way to achieve what you're trying to do. You could e.g. calculate the length and something like a checksum over your text and put a unique constraint on those length and checksum columns.
One way to do this would be to add a column for a hash that is calculated whenever you insert or update the column and put a unique index on that. While hash collisions do happen, it is extremely unlikely.
You could use this T-SQL keyword:
http://msdn.microsoft.com/en-us/library/ms174415.aspx
Even if this were possible, it would be a bad idea.
1) There is another way. Find some other data to use as your unique column
2) If you ABSOLUTELY HAVE TO use the varchar(Max). Maybe hash it on insert/update and add a hash column?
Is it beneficial to add an index to a column that is part of a foreign key relationship? I have two columns which will be queried frequently and already have them foreign keyed but wasn't sure if I should index them aswell, or if the foreign key creates an index behind the scenes?
SQL Server does not create a behind the scenes index, so creating an index on all foreign key fields is advisable to improve look up performance.
Details and additional benefits: http://technet.microsoft.com/en-us/library/ms175464.aspx
It is defenitely advisable to add an index to your FK column if you query it often.
In your situation, it is probably even better if you create a composite index which spans your 2 columns.
This is only advisable however (composite index) , if you often execute queries that filter / order on these 2 columns.
If you decide that a composite index is appropriate, then you should pay attention to the order in which you put an index on those columns.
Creating an index for your FK fields is strongly adviseable - this will almost definitely improve performance. Note that's for selects, inserts may be slower as the index itself will also have to be updated.
Sql Server will sometimes create an FK index 'on the fly' but that only exists for the lifetime of your query - you can look at the Sql Execution plan to see if that is occuring. Either way, creating your own index, under your control for FK fields is the way to go.