Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 192339
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 11, 20262026-05-11T16:25:04+00:00 2026-05-11T16:25:04+00:00

I am currently developing on an advertising system, which have been running just fine

  • 0

I am currently developing on an advertising system, which have been running just fine for a while now, apart from recently when our views per day have shot up from about 7k to 328k. Our server cannot take the pressure on this anymore – and knowing that I am not the best SQL guy around (hey, I can make it work, but not always in the best way) I am asking here for some optimization guidelines. I hope that some of you will be able to give rough ideas on how to improve this – I don’t specifically need code, just to see the light :).

As it is at the moment, when an advert is supposed to be shown a PHP script is called, which in return calls a stored procedure. This stored procedure does several checks, it tests up against our customer database to see if the person showing the advert (given by a primary key id) is an actual customer under the given locale (our system is running on several languages which are all run as separate sites). Next up is all the advert details fetched out (image location as an url, height and width of the advert) – and lest step calls a separate stored procedure to test if the advert is allowed to be shown (is the campaign expired by either date or number of adverts allowed to show?) and if the customer has access to it (we got 2 access systems running, a blacklist and a whitelist one) and lastly what type of campaign we’re running, is the view unique and so forth.

The code consists of a couple of stored procedures that I will post in here.

— procedure called from PHP

CREATE PROCEDURE [dbo].[ExecView]

    (
    @publisherId bigint,
    @advertId bigint,
    @localeId int,
    @ip varchar(15),
    @ipIsUnique bit,
    @success bit OUTPUT,
    @campaignId bigint OUTPUT,
    @advert varchar(500) OUTPUT,
    @advertWidth int OUTPUT,
    @advertHeight int OUTPUT
    )

AS
BEGIN
    SET NOCOUNT ON;
    DECLARE @unique bit
    DECLARE @approved bit
    DECLARE @publisherEarning money
    DECLARE @advertiserCost money
    DECLARE @originalStatus smallint
    DECLARE @advertUrl varchar(500)
    DECLARE @return int

    SELECT @success = 1, @advert = NULL, @advertHeight = NULL, @advertWidth = NULL


    --- Must be valid publisher, ie exist and actually be a publisher
    IF dbo.IsValidPublisher(@publisherId, @localeId) = 0
        BEGIN
            SELECT @success = 0
            RETURN 0
        END

    --- Must be a valid advert
    EXEC @return = FetchAdvertDetails @advertId, @localeId, @advert OUTPUT, @advertUrl OUTPUT, @advertWidth OUTPUT, @advertHeight OUTPUT

    IF @return = 0
        BEGIN
            SELECT @success = 0
            RETURN 0
        END 

    EXEC CanAddStatToAdvert 2, @advertId, @publisherId, @ip, @ipIsUnique, @success OUTPUT, @unique OUTPUT, @approved OUTPUT, @publisherEarning OUTPUT, @advertiserCost OUTPUT, @originalStatus OUTPUT, @campaignId OUTPUT

    IF @success = 1
        BEGIN   
            INSERT INTO dbo.Stat (AdvertId, [Date], Ip, [Type], PublisherEarning, AdvertiserCost, [Unique], Approved, PublisherCustomerId, OriginalStatus)
            VALUES (@advertId, GETDATE(), @ip, 2, @publisherEarning, @advertiserCost, @unique, @approved, @publisherId, @originalStatus)
        END

END

— IsValidPublisher

CREATE FUNCTION [dbo].[IsValidPublisher] 
(
    @publisherId bigint,
    @localeId int
)
RETURNS bit
AS
BEGIN
    DECLARE @customerType smallint
    DECLARE @result bit

    SET @customerType = (SELECT [Type] FROM dbo.Customer
    WHERE CustomerId = @publisherId AND Deleted = 0 AND IsApproved = 1 AND IsBlocked = 0 AND LocaleId = @localeId)

    IF @customerType = 2
        SET @result = 1
    ELSE
        SET @result = 0

    RETURN @result  
END

— Fetch advert details

CREATE PROCEDURE [dbo].[FetchAdvertDetails] 
    (
        @advertId bigint,
        @localeId int,
        @advert varchar(500) OUTPUT,
        @advertUrl varchar(500) OUTPUT,
        @advertWidth int OUTPUT,
        @advertHeight int OUTPUT
    )
AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    SELECT @advert = T1.Advert, @advertUrl = T1.TargetUrl, @advertWidth = T1.Width, @advertHeight = T1.Height FROM Advert as T1
    INNER JOIN Campaign AS T2 ON T1.CampaignId = T2.Id
    WHERE T1.Id = @advertId AND T2.LocaleId = @localeId AND T2.Deleted = 0 AND T2.[Status] <> 1

    IF @advert IS NULL
        RETURN 0
    ELSE
        RETURN 1
END

— CanAddStatToAdvert

CREATE PROCEDURE [dbo].[CanAddStatToAdvert] 
    @type smallint, --- Type of stat to add
    @advertId bigint,
    @publisherId bigint,
    @ip varchar(15),
    @ipIsUnique bit,
    @success bit OUTPUT,
    @unique bit OUTPUT,
    @approved bit OUTPUT,
    @publisherEarning money OUTPUT,
    @advertiserCost money OUTPUT,
    @originalStatus smallint OUTPUT,
    @campaignId bigint OUTPUT
AS
BEGIN
    SET NOCOUNT ON;
    DECLARE @campaignLimit int
    DECLARE @campaignStatus smallint
    DECLARE @advertsLeft int
    DECLARE @campaignType smallint
    DECLARE @campaignModeration smallint
    DECLARE @count int

    SELECT @originalStatus = 0
    SELECT @success = 1
    SELECT @approved = 1
    SELECT @unique = 1

    SELECT @campaignId = CampaignId FROM dbo.Advert
    WHERE Id = @advertId

    IF @campaignId IS NULL
        BEGIN
            SELECT @success = 0
            RETURN
        END

    SELECT @campaignLimit = Limit, @campaignStatus = [Status], @campaignType = [Type], @publisherEarning = PublisherEarning, @advertiserCost = AdvertiserCost, @campaignModeration = ModerationType FROM dbo.Campaign
    WHERE Id = @campaignId


    IF (@type <> 0 AND @type <> 2 AND @type <> @campaignType) OR ((@campaignType = 0 OR @campaignType = 2) AND (@type = 1)) -- if not a click or view type, then type must match the campaign (ie, only able to do leads on lead campaigns, no isales or etc), click and view campaigns however can do leads too
        BEGIN
            SELECT @success = 0
            RETURN
        END

    -- Take advantage of the fact that the variable only gets touched if there is a record,
    -- which is supposed to override the existing one, if there is one
    SELECT @publisherEarning = Earning FROM dbo.MapCampaignPublisherEarning
    WHERE CanpaignId = @campaignId AND PublisherId = @publisherId

    IF @campaignStatus = 1
        BEGIN
            SELECT @success = 0
            RETURN
        END

    IF NOT @campaignLimit IS NULL
        BEGIN
            SELECT @advertsLeft = AdvertsLeft FROM dbo.Campaign WHERE Id = @campaignId
            IF @advertsLeft < 1
                BEGIN
                    SELECT @success = 0
                    RETURN
                END
        END

    IF @campaignModeration = 0 -- blacklist
        BEGIN
            SELECT @count = COUNT([Status]) FROM dbo.MapCampaignModeration WHERE CampaignId = @campaignId AND PublisherId = @publisherId AND [Status] = 3
            IF @count > 0
                BEGIN
                    SELECT @success = 0
                    RETURN
                END
        END
    ELSE -- whitelist
        BEGIN
            SELECT @count = COUNT([Status]) FROM dbo.MapCampaignModeration WHERE CampaignId = @campaignId AND PublisherId = @publisherId AND [Status] = 2
            IF @count < 1
                BEGIN
                    SELECT @success = 0
                    RETURN
                END
        END

    IF @ipIsUnique = 1
        BEGIN
            SELECT @unique = 1
        END
    ELSE
        BEGIN
            IF (SELECT COUNT(T1.Id) FROM dbo.Stat AS T1
                            INNER JOIN dbo.IQ_Advert AS T2
                            ON T1.AdvertId = T2.Id
                            WHERE T2.CampaignId = @campaignId
                            AND T1.[Type] = @type
                            AND T1.[Unique] = 1
                            AND T1.PublisherCustomerId = @publisherId
                            AND T1.Ip = @ip
                            AND DATEADD(SECOND, 86400, T1.[Date]) > GETDATE()
              ) = 0 
                SELECT @unique = 1
             ELSE
             BEGIN
                SELECT @unique = 0, @originalStatus = 1 -- not unique, and set status to be ip conflict
             END

        END

    IF @unique = 0 AND @type <> 0 AND @type <> 2
    BEGIN
        SELECT @unique = 1, @approved = 0
    END

    IF @originalStatus = 0
        SELECT @originalStatus = 5

    IF @approved = 0 OR @type <> @campaignType
    BEGIN
        SELECT @publisherEarning = 0, @advertiserCost = 0
    END

END

I am thinking this needs more than just a couple of indexes thrown in to help it, but rather a total rethinking of how to handle it. I have been heard that running this as a batch would help, but I am not sure how to get this implemented, and really not sure if i can implement it in a such way where I keep all these nice checks before the actual insert or if I have to give up on some of this.

Anyhow, all help would be appreciated, if you need any of the table layouts, let me know :).

Thanks for taking the time to look at it 🙂

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-11T16:25:04+00:00Added an answer on May 11, 2026 at 4:25 pm

    Make sure to reference tables with the ownership prefix. So instead of:

    INNER JOIN Campaign AS T2 ON T1.CampaignId = T2.Id
    

    Use

    INNER JOIN dbo.Campaign AS T2 ON T1.CampaignId = T2.Id
    

    That will allow the database to cache the execution plan.

    Another possibility is to disable database locking, which has data integrity risks, but can significantly increase performance:

    INNER JOIN dbo.Campaign AS T2 (nolock) ON T1.CampaignId = T2.Id
    

    Run a sample query in SQL Analyzer with “Show Execution Plan” turned on. This might give you a hint as to the slowest part of the query.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

No related questions found

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.