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

  • Home
  • SEARCH
  • 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 512171
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 13, 20262026-05-13T07:17:33+00:00 2026-05-13T07:17:33+00:00

I’m implementing the following access policy: a User can access a Resource if he

  • 0

I’m implementing the following access policy: a User can access a Resource if he created it, belongs to the Resource‘s group members or if the resource is publicly available.

Here is my DB structure (tables are MyISAM):

User (1K-10K Users)
  id
  nickame
  …
  index user_name(id, nickname)
Group (1K)
  id
  …
Resource (10K-100K)
  id
  user_id
  access_type (int)
  group_id
  created (int/timestamp)
  …
  indexes by_user(user_id, created), by_group(access_type, group_id, created), public(access_type, created)
User_Group (5K-20K)
  user_id
  group_id
  membership_type (int)
  index user_group(user_id, membership_type, group_id)

The conditions to grant access are implemented this way:
* The User is the creator of the Resource (user_id = <his id>, whatever access_type is)
* Or the ressource is publicly available: Resource.access_id = 3
* Or the ressource is shared in a group and the User is accepted as “member” of this group:
** Resource.access_id = 2 (shared in a group)
** Ressource.group_id matches a User_Group‘s group_id
** this User_Group‘s user_id matches the User’s id
** this User_Group‘s membership_type is 1, 2 or 3 (accepted member or group moderator/admin)

My question is: what is the most efficient way to list the Resources (and the Resource creator’s nickname) that are accessible to the User when we have his ID. And ordered by the Resource’s created timestamp.

My best attempt so far is to use an UNION that allows using both by_user and by_group indexes, but might struggle in the sorting afterwards:

SELECT SQL_NO_CACHE
  a.*, user.nickname
FROM (
  ( SELECT resource.* FROM resource WHERE user_id = '000000-0000-0000-0000-000000000000' )
UNION
  ( SELECT resource.* FROM resource WHERE access_type = 3 )
UNION
  ( SELECT resource.* FROM resource
   INNER JOIN user_group ON (access_type = 2 AND user_group.group_id = resource.group_id)
   WHERE user_group.user_id = '000000-0000-0000-0000-000000000000'
    AND user_group.type IN (1, 2, 3)
  )
) a
LEFT JOIN user ON (user.id = a.user_id)
ORDER BY created DESC;

The EXPLAIN output tells me it uses the indexes for both SELECTs and finishes with a type: ALL / Using filesort for the ORDER BY on UNION-ed rows. But if I want to order and limit, this can get heavy, I guess, since there is no index on UNION-ed tuples.

The other possibility is a simpler query with a subquery for the Groups the User is in:

SELECT SQL_NO_CACHE
  resource.*, user.nickname
FROM resource
LEFT JOIN user ON (user.id = resource.user_id) 
WHERE user_id = '000000-0000-0000-0000-000000000000'
  OR access_type = 3
  OR (access_type = 2 AND group_id IN
   ( SELECT group_id FROM user_group USE INDEX (`user_group`)
   WHERE user_id = '000000-0000-0000-0000-000000000000' AND type IN (1, 2, 3)
   )
  )
ORDER BY created DESC;

But here the EXPLAIN tells me it won’t use the index and performs a selection type: ALL / Using where; using filesort in the Resource table, witch is what I’m trying to avoid. If I try to FORCE INDEX(by_user, by_group), it is starts by merging both indexes type: index_merge / Using sort_union(by_user,by_group); Using where; Using filesort, which can be costly too.

Any better idea ? This request may be very frequently called…

  • 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-13T07:17:33+00:00Added an answer on May 13, 2026 at 7:17 am

    I think a second join will better utilize indexes here versus the subquery you suggested (just need to add a DISTINCT to avoid duplicates).

      SELECT SQL_NO_CACHE DISTINCT
             resource.*, user.nickname
        FROM resource
    LEFT JOIN user ON user.id = resource.user_id
    LEFT JOIN user_group ON user_group.user_id = user.id AND user_group.type IN (1, 2, 3)
        WHERE user_id = '000000-0000-0000-0000-000000000000'
           OR access_type = 3
          OR (access_type = 2 AND group_id IS NOT NULL)
    ORDER BY created DESC;
    

    Any time your primary WHERE clause is a sequence of OR’s, the ideal EXPLAIN result will be some type of index_merge. However, you are correct that sort_union is the slowest of these. If you read up on index_merge, particularly the sub parts about each type of merge, it becomes clear that the OR pieces of your WHERE clause need to reference all parts of a key, otherwise you’ll get a sort_union. So you should get a better EXPLAIN result if you had resource indexes:

    Resource (10K-100K)
    id
    user_id
    access_type (int)
    group_id
    created (int/timestamp)
    …
    indexes 
        just_user(user_id),
        by_user(user_id, created),
        just_access(access_type),
        just_access_group(access_type, group_id),
        by_group(access_type, group_id, created),
        public(access_type, created)
    

    I recognize that this seems to contradict that you get left prefixes as indexes for free when you do multi-part keys but it seems the index_merge algorithm can’t (yet?) utilize those partial prefix indexes.

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

Sidebar

Ask A Question

Stats

  • Questions 297k
  • Answers 297k
  • Best Answers 0
  • User 1
  • Popular
  • Answers
  • Editorial Team

    How to approach applying for a job at a company ...

    • 7 Answers
  • Editorial Team

    What is a programmer’s life like?

    • 5 Answers
  • Editorial Team

    How to handle personal stress caused by utterly incompetent and ...

    • 5 Answers
  • Editorial Team
    Editorial Team added an answer #include <vector> #include <iostream> using namespace std; int main() {… May 13, 2026 at 7:23 pm
  • Editorial Team
    Editorial Team added an answer Warning: Since this post was written in 2010, GPUs have… May 13, 2026 at 7:23 pm
  • Editorial Team
    Editorial Team added an answer You can use function_exists() to test if a function with… May 13, 2026 at 7:23 pm

Related Questions

I'm trying to decode HTML entries from here NYTimes.com and I cannot figure out
I want use html5's new tag to play a wav file (currently only supported
I ran into a problem. Wrote the following code snippet: teksti = teksti.Trim() teksti
I've got a string that has curly quotes in it. I'd like to replace
In order to apply a triggered animation to all ToolTip s in my app,

Trending Tags

analytics british company computer developers django employee employer english facebook french google interview javascript language life php programmer programs salary

Top Members

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.