|
Chad3F wrote: After all, at one time, how many people had the opinion the world was flat and
the best practice was not to sail too far out?
At the time when people did in fact think the world was flat then in fact is was foolhardy to sail too far out because one was very likely to not return. Which was a loss both in lives and commerce.
|
|
|
|
|
Yes, those that sailed too far likely had a greater chance of something going wrong (per voyage).. but statistically over all, I expect out of all ships/lives lost that only a small percentage were from those sailing out too far. Most had no reason to try (unless they were explorers), so most of the risk was while in known waters (so why not have a best practice of never sailing period). This would be like most people not routinely driving more than 1000 miles (or kilometers) from their home (unless it was required of their job).. hence the [paraphrased] expression of "most [driving] accidents occur within X distance of ones home", simply because that is where the are [on the road] most of the time.
In the end, just because something is done for the wrong reasons (i.e. to not fall off the end of the world) and happens to be useful (i.e. less lost lives/cargo), doesn't justify the basis (a variation of "the ends don't justify the means" I suppose). As an example, if a parent tells a young child not to talk to strangers, "just because", but not why explain why (since the child would unlikely be capable of comprehending why anyway), then that may work on the short term.. but, if left at that, in the long term it could be disastrous. Imagine if that child follows that directive to the letter "just because" their parent said so and one day there is a house fire, firefighters come and surround the house with the kid still inside. Now the child sees all these strangers and has to make a choice.. does he go outside, where all these strangers are, and break the rule.. or does he stay inside (or even hide, since several strangers are entering the house for some reason) to avoid them? A slightly contrived scenario (but not impossible) that illustrates how blindly following a "rule" without understanding why can [eventually] lead to a worse outcome than what the rule was indented to avoid. In some cases, like a young child's limited comprehension, you have to try and account for exceptions when stating the rule.. but when comprehension is possible, ignorant, "just because" logic is never an acceptable reason to do something. One should know _why_ something is better to use than another, in which case they shouldn't _need_ to be told to what [specifically] to do for the best, as it is the automatic choice (including _when_ to break the default choice). If I know a wood chipper chops up materials you put in it, and I know one is [potentially] running, then I implicitly choose not to put my hand in it.. I don't need to be told NOT to do that as a best practice. Yes, they still put that warning sign on it.. I guess because some [adult] people are ignorant of how a chipper works (which in itself is inexcusable).
I think the fact that [so-called] "best practices" exists is in some ways related to how people are taught.. far too much rote learning and not enough understanding. Rote is fine for forming a basic foundation before enough knowledge can be amassed to achieve understanding, but becomes a hindrance after that. In other words.. Teach someone 10 facts, without understanding, and that person knows 10 things. Teach that same person 10 concepts, with understanding, and now they know 100's or even 1000's of things (i.e. the meaningful combinations of those 10 concepts).
|
|
|
|
|
Chad3F wrote: and happens to be useful (i.e. less lost lives/cargo), doesn't justify the basis
Yes as a matter of a fact it does.
Most software development exists to fulfill a need, often either an explicitly or even implicitly commercial.
Just as sailing a ship did. Exploring might be 'fun' or 'cool' but the rate of return is very low. Whereas staying with the known routes provided a known rate of return. And that is what businesses want. They don't want fun/cool. They want money.
Chad3F wrote: Teach that same person 10 concepts, with understanding, and now they know 100's or even 1000's of things (i.e. the meaningful combinations of those 10 concepts)
Of course that is what one wants. But one also wants every one to be a multi-talented genius as well and it just doesn't happen.
|
|
|
|
|
I know the show that kills Kenny, because of an article I read that talks about it. (At least if I see the show's name, I'll also remember it kills Kenny) The article didn't say why they kill Kenny and I've only watched about 40 seconds tops to see if I wanted to watch it. Is it some group mindset that causes them to want to kill Kenny? Of course the writers put it in because it is funny to constantly kill the same person over and over and... (Which is why I could stand about 40 seconds of their humor.)
What a scalawag that Columbus was, eh? I also like your alternative definition of best practices.
|
|
|
|
|
The "Kenny" reference was to indicate that the "They" context I was using was not a specific, or even tangible, group (such as an official standards body, like IETF, ISO, IEEE, ANSI, etc..). But instead was the unknown and mysterious "powers that be" (in the context of defining so-called "best" anything) that define "best practice" lists.
As for the origin behind the actual killing of Kenny.. I guess it started out as some form of joke in the show (e.g. this poor kid Kenny just can't catch a break), and just kept on going from there. Eventually they stopped doing it [regularly] (maybe they ran out of "interesting" ways for Kenny to die). I'm sure there is probably an official response from Trey Parker and/or Matt Stone (its creators) about the subject on some fan site/FAQ/forum out there.
|
|
|
|
|
It's best to avoid "best practices".
|
|
|
|
|
Unless you're talking about a really old (.NET 1) version of the compiler, this is translated internally into the following il:
.field private static literal string SQL = string('SELECT ID, NAME, BIRTHDAY FROM TABLE WHERE NAME LIKE @PARAM') As you can see, there's no concatenation in there at all.
|
|
|
|
|
I know there is no concatenation. Any const must be resolved at compile time.
When I said that I "think it optimizes" I put the because it is obvious.
|
|
|
|
|
That was meant for you to beat them round the head with, rather than for your benefit.
|
|
|
|
|
Didn't even the 1.0 compiler do that with string constants?
|
|
|
|
|
BobJanova wrote: Didn't even the 1.0 compiler do that I, too, was surprised by that, however I learned C# around 2.3 or later so I bought it even though it seemed odd with a const declaration.
|
|
|
|
|
There are a lot of people who encounter "best practices", turn off the brain and spew out nonsense, a constant is evaluated once on the JIT compile and that is the last time it uses the string add.
Of course the DBA that gives a programmer direct read access to a table needs to be led out and shot....
There are good reasons for using StringBuilder, but that isn't one of them. I intentionally did string concatenation in my code to see how much StringBuilder helps. I got the code to work adding the statistics I gathered into a string. It ran in about 35 minutes. I added StringBuilder and cut the time to 15 minutes. I then added code to only convert the stats I built when I found a solution (several thousand) instead of when I created the stats (several million) and cut it down to 7 minutes. Finally I played around with the order of how the puzzle was solved and cut it to 4 minutes. My next improvement cut it down to 2 minutes. (Purchaced a computer with twice the rate of processing.)
|
|
|
|
|
I am not sure what you are trying to do, but see very little reason is having separate strings for this in the first place. Can be represented as a single string. I would also guess that the complier will concantinate everyting, so trying to use a StringBuilder will probalby slow everything down.
|
|
|
|
|
The compiler will make everything into a single string... and I was presenting this as a coding horrer exactly because the many + that were done as const were being replaced by stringbuilders.
|
|
|
|
|
Why not do ?
private const string SQL =
@"SELECT
ID,
NAME,
BIRTHDAY
FROM
TABLE
WHERE
NAME LIKE @PARAM";
It allows you to cut n paste the code into a SQL dev tool to test it and its easier to maintain without the extra quotes and +'s.
|
|
|
|
|
Because it was a coding horror.
|
|
|
|
|
Here is a simple stored procedure in company database that does a search and returns results in less than a second:
CREATE PROCEDURE [dbo].[WorkOrder_Search](@Description varchar(250))
AS
Begin
SELECT Order_id,Dept_Code,Graphic_Number,[Description],Quantity,Date_Received as [Recv. Date],Date_Due as [Due Date],
Date_Delivered as [Delivered Date],proof_sent_date as [Proof Date],print_date as [To Print],
dbo.func_grOrder_GetAssigned(Order_id) as [Assign To],Status,Note, Master_Cal_ID
From grGraphic_Order
where [Description] like '%' + @Description + '%'
end
But it used to be a really "BIG" stored procedure as shown below that did the same search and took about 5 minutes to return results. It did return the same results as the above does.
CREATE PROCEDURE [dbo].[WorkOrder_search](@Description varchar(250))
AS
begin
SET QUOTED_IDENTIFIER OFF
SET ANSI_NULLS OFF
SET NoCount ON
Declare @sql varchar(8000)
Declare @Orig_1 varchar(1000)
Declare @Declare varchar(200),
@From varchar(100),@Into varchar(50),@Groupby varchar(300),
@Orderby varchar(400),@Select varchar(400),@Select1 varchar(400),@Select2 varchar(300),
@cursor1 varchar (500),@cursor2 varchar(4000),@create varchar(4000)
set @Orig_1 = ''
Create table #Assignto_temp(Order_id int, Assignto_names varchar(500))
Insert into #Assignto_temp(Order_id )
Select gro.order_id
From grassignto gro
Inner join wfpmauser wf
On gro.user_id = wf.user_id
group by gro.order_id
declare @order_number int, @Assignto varchar(255), @List_names varchar(255),@order_number_prev int
declare assignto Cursor
Local
Forward_only
for
Select gro.order_id,Wf.First_name+' '+Wf.Last_name as Assignto
From grassignto gro
Inner join wfpmauser wf
On gro.user_id = wf.user_id
order by order_id
open assignto
Fetch Next from assignto into @order_number, @Assignto
While @@Fetch_Status=0
begin
select @List_names=Assignto_names from #Assignto_temp where order_id=@order_number
if @List_names is null
begin
update #Assignto_temp
set Assignto_names=@Assignto
where order_id=@order_number
end
else
begin
update #Assignto_temp
set Assignto_names=@list_names + ',' + @Assignto
where order_id=@order_number
end
Fetch Next from assignto into @order_number, @Assignto
end
close assignto
deallocate assignto
Set @Declare ="Declare @Orig_1 varchar(1000),@Originator varchar(100),@order_id int,@Orig varchar(300) set @Orig_1 = '' "
Set @Select = " SELECT distinct gro.* "
Set @Into = "Into #tmp1 "
Set @From = "FROM grGraphic_Order Gro left join grOriginator gr on gro.order_id = gr.order_id "
Set @Orderby = "ORDER BY Gro.Graphic_number,Gro.dept_code Desc "
Set @Select2 = " SELECT Order_id,Dept_Code ,Graphic_Number,Description,Quantity,Date_Received as [Recv. Date],
Date_Due as [Due Date],Date_Delivered as [Delivered Date],proof_sent_date as [Proof Date],print_date as [To Print],
Status,Note, master_cal_id [Master Calendar ID] From #tmp1 ORDER BY dept_code,Graphic_number "
Set @Create = "Create table #Assignto_temp(Order_id int, Assignto_names varchar(500))
Insert into #Assignto_temp(Order_id )
Select gro.order_id
From grassignto gro
Inner join wfpmauser wf
On gro.user_id = wf.user_id
group by gro.order_id
declare @order_number int, @Assignto varchar(255), @List_names varchar(255),@order_number_prev int
declare assignto Cursor
Local
Forward_only
for
Select gro.order_id,Wf.First_name+' '+Wf.Last_name as Assignto
From grassignto gro
Inner join wfpmauser wf
On gro.user_id = wf.user_id
order by order_id
open assignto
Fetch Next from assignto into @order_number, @Assignto
While @@Fetch_Status=0
begin
select @List_names=Assignto_names from #Assignto_temp where order_id=@order_number
if @List_names is null
begin
update #Assignto_temp
set Assignto_names=@Assignto
where order_id=@order_number
end
else
begin
update #Assignto_temp
set Assignto_names=@list_names + ',' + @Assignto
where order_id=@order_number
end
Fetch Next from assignto into @order_number, @Assignto
end
close assignto
deallocate assignto
SELECT #tmp1.Order_id,Dept_Code ,Graphic_Number,Description,Quantity,Date_Received as [Recv. Date],
Date_Due as [Due Date],Date_Delivered as [Delivered Date],proof_sent_date as [Proof Date],print_date as [To Print],
isnull(tmp.assignto_names,'Not Assigned') as [Assign To],Status,Note, #tmp1.Master_Cal_ID
From #tmp1 LEFT Join #Assignto_temp tmp ON #tmp1.order_id = tmp.order_id ORDER BY Dept_Code,Date_Received Desc"
Select @sql=@Declare + @Select + @Into + @From + ' where Description like '
+ char(39) + '%' + @Description + '%' + char(39)+ @Orderby + @create
Exec(@sql)
end
TOMZ_KV
modified 13-Apr-13 8:57am.
|
|
|
|
|
pssssst. Use pre blocks to make your code pretty.
Gryphons Are Awesome! Gryphons Are Awesome!
|
|
|
|
|
Pretty? Pretty?
You'd need a very large magnet and a flare gun to make that code pretty!
The universe is composed of electrons, neutrons, protons and......morons. (ThePhantomUpvoter)
|
|
|
|
|
Obviously the old code is a hideous display of incompetence what with the gratitious use of cursors (not even FAST_FORWARD at that) and temp tables in dynamic SQL no less, but I think the new code is missing an ORDER BY Graphic_number ASC, Dept_code DESC (with matching nonclustered indexes on the table) and probably could be improved by an inline table valued function with a CROSS APPLY in place of dbo.func_grOrder_GetAssigned(Order_id) and a FULLTEXT index for the Description column to avoid the non-SARGable wildcard prefix.
modified 14-Apr-13 2:54am.
|
|
|
|
|
|
And now? When your boss tells you that the application is slow, where will you find some lines for easy improvements?
|
|
|
|
|
What would you suggest to do?
TOMZ_KV
|
|
|
|
|
Sprinkle WAITFOR DELAY '00:00:01' (or a more appropriate value, do a performance analysis first; it should run faster than the old unoptimized version) judiciously across your newly optimized SPs, so you still have room for improvement.
|
|
|
|
|
How can you be sure that both procedures are doing the same? I mean in all cases, not just on a few test cases.
|
|
|
|
|