После работы в среде, которая имела очень определенные и очень бессмысленные правила стиля с тех пор, я продолжал создавать свой собственный стиль. Это - один тип, на котором я зеркально отразил назад и вперед много. Я наконец решил, что частные поля всегда будут _field, локальные переменные никогда не будут иметь _ и будут нижним регистром, имена переменной для средств управления будут свободно следовать за Венгерской записью, и параметры обычно будут Camel-регистром.
я ненавижу this.
ключевое слово, оно просто добавляет слишком много шума кода, по-моему. Я люблю Resharper, удаляют избыточный это. ключевое слово.
6-летнее обновление: я анализировал внутренности Dictionary<TKey,T>
для определенного использования параллельного доступа и неправильно читал частное поле, чтобы быть локальной переменной. Частные поля определенно не должны быть тем же соглашением о присвоении имен как локальные переменные. Если бы было подчеркивание, то это было бы невероятно очевидно.
Каждая опция, которая включает манипуляции CAST, TRUNCATE или DATEPART в поле datetime, имеет одну и ту же проблему: запрос должен сканировать весь набор результатов (40k), чтобы найти отдельные даты. Производительность может незначительно отличаться между различными реализациями.
Что вам действительно нужно, так это иметь индекс, который может мгновенно дать ответ. У вас может быть либо постоянный вычисляемый столбец с индексом, который (требует изменения структуры таблицы), либо индексированное представление ( требуется Enterprise Edition для QO, чтобы учесть индекс из коробки).
Постоянный вычисляемый столбец:
alter table foo add date_only as convert(char(8), [datetimecolumn], 112) persisted;
create index idx_foo_date_only on foo(date_only);
Индексированное представление:
create view v_foo_with_date_only
with schemabinding as
select id
, convert(char(8), [datetimecolumn], 112) as date_only
from dbo.foo;
create unique clustered index idx_v_foo on v_foo_with_date_only(date_only, id);
Обновление
Чтобы полностью исключить сканирование, можно использовать индексированное представление с обманом GROUP BY, например:
create view v_foo_with_date_only
with schemabinding as
select
convert(char(8), [d], 112) as date_only
, count_big(*) as [dummy]
from dbo.foo
group by convert(char(8), [d], 112)
create unique clustered index idx_v_foo on v_foo_with_date_only(date_only)
Запрос выберите отдельный date_only из foo
вместо этого будет использовать это индексированное представление. Технически это все еще сканирование, но по уже «отдельному» индексу, поэтому сканируются только необходимые записи. Я считаю, что это хитрость, я бы не рекомендовал ее для реального производственного кода.
AFAIK SQL Server не имеет возможности сканировать истинный индекс с пропуском повторов, т.е. ищите вершину, затем ищите больше вершины, затем последовательно ищите больше последней найденной.
Я использовал следующее:
CAST(FLOOR(CAST(@date as FLOAT)) as DateTime);
Это удаляет время из даты, преобразовывая его в float
и обрезая "временная" часть,
Самый простой способ - добавить вычисляемый столбец только для части даты и выбрать его. Вы можете сделать это в представлении, если не хотите изменять таблицу.
нос будет прерван только при первом сбое, если вы передадите параметр -x
в командной строке.
test.py:
def test1():
assert False
def test2():
assert False
без параметра -x :
C:\temp\py>C:\Python26\Scripts\nosetests.exe test.py FF ====================================================================== FAIL: test.test1 ---------------------------------------------------------------------- Traceback (most recent call last): File "C:\Python26\lib\site-packages\nose-0.11.1-py2.6.egg\nose\case.py", line 183, in runTest self.test(*self.arg) File "C:\temp\py\test.py", line 2, in test1 assert False AssertionError ====================================================================== FAIL: test.test2 ---------------------------------------------------------------------- Traceback (most recent call last): File "C:\Python26\lib\site-packages\nose-0.11.1-py2.6.egg\nose\case.py", line 183, in runTest self.test(*self.arg) File "C:\temp\py\test.py", line 5, in test2 assert False AssertionError ---------------------------------------------------------------------- Ran 2 tests in 0.031s FAILED (failures=2)
с параметром -x:
C:\temp\py>C:\Python26\Scripts\nosetests.exe test.py -x F ====================================================================== FAIL: test.test1 ---------------------------------------------------------------------- Traceback (most recent call last): File "C:\Python26\lib\site-packages\nose-0.11.1-py2.6.egg\nose\case.py", line 183, in runTest self.test(*self.arg) File "C:\temp\py\test.py", line 2, in test1 assert False AssertionError ---------------------------------------------------------------------- Ran 1 test in 0.047s FAILED (failures=1)
Вы можете рассмотреть возможность просмотра документации носа .
WITH rows AS (
SELECT CAST(CAST(CAST(MIN(date) AS FLOAT) AS INTEGER) AS DATETIME) AS mindate, MAX(date) AS maxdate
FROM mytable
UNION ALL
SELECT mindate + 1, maxdate
FROM rows
WHERE mindate < maxdate
)
SELECT mindate
FROM rows
WHERE EXISTS
(
SELECT NULL
FROM mytable
WHERE date >= mindate
AND date < mindate + 1
)
OPTION (MAXRECURSION 0)
Это будет более эффективно, чем Stream Aggregate
Каков ваш предикат для этого другого отфильтрованного столбца? Пробовали ли вы улучшить индекс этого другого отфильтрованного столбца, за которым следует поле datetime?
Я в основном предполагаю, но 5 секунд, чтобы отфильтровать набор из 100000 строк до 40000, а затем выполнить sort (что, по-видимому, и происходит) мне не кажется необоснованным. Почему ты говоришь, что это слишком медленно? Потому что это не соответствует ожиданиям?
Просто преобразуйте дату: dateadd (dd, 0, datiff (dd, 0, [Some_Column]))
Если вы хотите избежать поэтапного извлечения или переформатирования даты - что, по-видимому, является основной причиной задержки (путем принудительного полного сканирования таблицы) - у вас нет альтернативы, кроме как сохранить date - это только часть даты и времени, что, к сожалению, потребует изменения структуры базы данных.
Если вы используете SQL Server 2005 или более поздней версии, то можно использовать постоянное вычисляемое поле
Unless otherwise specified, computed columns are virtual columns that are not physically stored in the table. Their values are recalculated every time they are referenced in a query. The Database Engine uses the PERSISTED keyword in the CREATE TABLE and ALTER TABLE statements to physically store computed columns in the table. Their values are updated when any columns that are part of their calculation change. By marking a computed column as PERSISTED, you can create an index on a computed column that is deterministic but not precise.
Я не уверен, почему ваш существующий запрос займет более 5 секунд для 40 000 строк.
Я только что попробовал следующий запрос к таблице со 100 000 строками, и он вернул менее 0,1 секунды.
SELECT DISTINCT DATEADD(day, 0, DATEDIFF(day, 0, your_date_column))
FROM your_table
(Обратите внимание, что этот запрос, вероятно, не будет иметь возможность использовать любые индексы в столбце даты, но это должно быть достаточно быстро, если предположить, что вы не выполняете его десятки раз в секунду.)