Getting stuck with creating better index (Optimize Join)
First, let's clean up the data.

Is Monthly a true/false value?  Then use 0/1 and put it in TINYINT NOT NULL.  Or is it tri-state:  Yes/No/unspecified?

If Off_comments is an optional string, then cleanse the data so that the empty string and '' are turned into NULL when it is stored.  (Meanwhile, one or two UPDATEs can clean up the data.)

I recommend those because OR is hard to optimize, and this will probably eliminate such.

LEFT says that the 'right' table is optional.  Yet AND t3... says that you must find a row.  So change both LEFT JOINs to JOINs.

Once that is done, it may be efficient to check for T3.frnd_id= '4' first instead of last.  Could it be that there aren't many rows with 4?

Indexes...

Assuming the above works, T3 needs INDEX(frnd_id, id), then T2 needs INDEX(On_site_id, id).

If the optimizer prefers to start with T1, first look for any = things in the WHERE.  But, the only possibility is monthly, depending on the discussion above.  Off_comments is not a candidate for indexing since it is TEXT.

I'll digress a moment.  What is T3 about?  It has only 50 rows?  Perhaps it is "over-normalization"?  If so, couldn't you simply put frnd_id into T2?

Grrr... Have you "simplified" the question?  This seems invalid:  social enum( 'Facebook','twitter') DEFAULT 'LI', since LI is not an option in the enum!

Grrr-squared...  This is probably not what you wanted:

`T1.createDate`


Instead:

`T1`.`createDate`


Please fix those and any other mis-simplifications!

T1 may be able to use INDEX(createDate).

One more thing:  1:1 relationships (T1.id = T2.id) are usually a questionable design.  Is id the PRIMARY KEY on both tables?