Uniqueness and Performance
Arguments FOR Declaring Uniqueness
It's typically better to provide more information to the optimizer rather than less. If you know that an index is unique, it's best to declare it that way. This can help the optimizer, as well as providing clarity about your data to actual people looking at the schema definitions.
This can have a direct impact on performance. See Paul White's article Enforcing Uniqueness for Performance for one such example.
Arguments AGAINST Declaring Uniqueness
As far as the specifics of this question, I tried to adapt your nonclustered index scenario to the demo in Paul's article, and it appears that singleton seeks are used whether the nonclustered index is declared unique or not. I've included the modified demo code at the end of this answer.
Based on that, it appears the optimizer is able to infer uniqueness by the inclusion of the UNIQUE key from the clustered index. This concept is more thoroughly confirmed and fleshed out in this Q&A: Should I mark a composite index as unique if it contains the primary key?
There are also certain scenarios where a UNIQUE index can cause performance overhead, so there's not a magic bullet answer here unfortunately. See these articles for related reading:
Index Key Ordering
Regarding the column ordering, that really depends on the types of queries that are going to be executed against this table. And this is more-or-less the "general" guidance about indexes that comes into play here. You generally want the "most selective" column first.
If queries are typically going to include a value for "Primary" as a filter (or join condition), then that's an ideal candidate - you can seek directly to the right row. If queries typically only provide a value for "Secondary", then Primary is not a good leading index key - you'd have to scan through every row in the table. In that case, Secondary is a better choice to lead the index.
Demo Code
See below for the code I used, again this is adapted (possibly incorrectly, as I am just a lowly web developer) from Paul's article:
SET STATISTICS TIME, IO ON; CREATE TABLE [dbo].[OnlyTwoGoodColumnsButManyBad] ( [Primary] INT PRIMARY KEY CLUSTERED, [Secondary] NVARCHAR(500) NOT NULL, [Evil1] NVARCHAR(MAX), [Evil2] NVARCHAR(MAX), [Evil3] NVARCHAR(MAX), [Evil4] NVARCHAR(MAX), [Evil5] NVARCHAR(MAX) ); INSERT dbo.OnlyTwoGoodColumnsButManyBad WITH (TABLOCKX) ([Primary], Secondary) SELECT TOP (5000000) [Primary] = ROW_NUMBER() OVER ( ORDER BY @@SPID), Secondary = 'Garbage' FROM master.sys.columns AS C CROSS JOIN master.sys.columns AS c2 CROSS JOIN master.sys.columns AS c3 ORDER BY [Primary]; CREATE NONCLUSTERED INDEX [IX_Primary_Secondary] ON [dbo].[OnlyTwoGoodColumnsButManyBad] ( [Primary], [Secondary] ); CREATE UNIQUE NONCLUSTERED INDEX [UIX_Primary_Secondary] ON [dbo].[OnlyTwoGoodColumnsButManyBad] ( [Primary], [Secondary] ); SELECT COUNT_BIG(*) FROM dbo.[OnlyTwoGoodColumnsButManyBad] AS ST WITH (TABLOCK, INDEX ([IX_Primary_Secondary])) JOIN dbo.[OnlyTwoGoodColumnsButManyBad] AS ST2 WITH (TABLOCK, INDEX ([IX_Primary_Secondary])) ON ST2.[Primary] = ST.[Primary] AND ST2.[Secondary] = ST.[Secondary] OPTION (MAXDOP 1, LOOP JOIN, FORCE ORDER); /* Table 'OnlyTwoGoodColumnsButManyBad'. Scan count 1, logical reads 15329888 CPU time = 5000 ms, elapsed time = 5312 ms. */ SELECT COUNT_BIG(*) FROM dbo.[OnlyTwoGoodColumnsButManyBad] AS ST WITH (TABLOCK, INDEX ([UIX_Primary_Secondary])) JOIN dbo.[OnlyTwoGoodColumnsButManyBad] AS ST2 WITH (TABLOCK, INDEX ([UIX_Primary_Secondary])) ON ST2.[Primary] = ST.[Primary] AND ST2.[Secondary] = ST.[Secondary] OPTION (MAXDOP 1, LOOP JOIN, FORCE ORDER); /* Table 'OnlyTwoGoodColumnsButManyBad'. Scan count 1, logical reads 15329888 CPU time = 4984 ms, elapsed time = 5283 ms. */